Menu
CoddyTech

do, try, catch

Thuộc phần Logic và luồng thực thi trong hành trình Swift của Coddy. Bài học 45 trên 56.

Cấu trúc đầy đủ để xử lý lỗi là do/try/catch:

enum DivError: Error { case byZero }

func divide(_ a: Int, _ b: Int) throws -> Int {
    if b == 0 { throw DivError.byZero }
    return a / b
}

do {
    let r = try divide(10, 2)
    print(r)                      // 5
} catch DivError.byZero {
    print("can't divide by zero")
} catch {
    print("unknown error")
}

try đứng trước bất kỳ lời gọi nào có thể phát sinh ngoại lệ. Nếu lời gọi phát sinh ngoại lệ, luồng điều khiển sẽ chuyển đến catch tương ứng; nếu không, chương trình tiếp tục chạy sau khối do.

Nhiều mệnh đề catch chạy lần lượt từ trên xuống dưới, và nhánh khớp đầu tiên sẽ được chọn, giống như switch. Mệnh đề catch không có đối số ở cuối sẽ bắt mọi ngoại lệ, bạn gần như luôn cần mệnh đề này để trình biên dịch không báo lỗi.

challenge icon

Thử thách

Dễ

Định nghĩa một enum ParseError: Error với ba trường hợp: empty, notInteger và negative.

Định nghĩa một hàm có thể ném lỗi parsePositive(_ s: String) throws -> Int với các chức năng sau:

  • Ném lỗi .empty khi s sau khi loại bỏ khoảng trắng là chuỗi rỗng
  • Ném lỗi .notInteger khi không thể phân tích s thành Int
  • Ném lỗi .negative khi giá trị đã phân tích là < 0
  • Nếu không thì trả về giá trị đã phân tích

Đọc một dòng từ stdin và gọi parsePositive trong khối do/catch. In ra:

  • got: <n> khi thành công
  • error: empty, error: not integer hoặc error: negative cho từng trường hợp

Với đầu vào 42, đầu ra là got: 42. Với một dòng trống, đầu ra là error: empty. Với abc, đầu ra là error: not integer.

Tự làm thử

let line = readLine()!

// TODO: enum ParseError; func parsePositive(_:) throws -> Int;
// do/try/catch với ba nhánh và một nhánh catch xử lý mọi trường hợp
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Logic và luồng thực thi

Tự luyện tập: Playground Swift