Menu
CoddyTech

do、try、catch

本课属于 Coddy Swift 学习旅程的“逻辑与流程”单元。第 45 课,共 56 课。

处理错误的完整形式是 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 放在任何可能抛出异常的调用前面。如果调用抛出异常,控制流会跳转到匹配的 catch;否则,执行会跳过 do 代码块继续进行。

多个 catch 子句会从上到下运行,第一个匹配的子句会生效,就像 switch 一样。末尾不带参数的 catch 用来捕获所有异常,你几乎总是需要加上它,这样编译器才不会报错。

challenge icon

挑战

简单

定义一个枚举 ParseError: Error,包含三个情况:empty、notInteger 和 negative。

定义一个会抛出异常的函数 parsePositive(_ s: String) throws -> Int,它:

  • 当去除空白字符后的 s 为空时,抛出 .empty
  • 当 s 无法解析为 Int 时,抛出 .notInteger
  • 当解析后的值 < 0 时,抛出 .negative
  • 否则,返回解析后的值

从 stdin 读取一行,并在 do/catch 块中调用 parsePositive。输出:

  • 成功时输出 got: <n>
  • 每种情况分别输出 error: empty、error: not integer 或 error: negative

输入 42 时,输出为 got: 42。输入空行时,输出为 error: empty。输入 abc 时,输出为 error: not integer。

亲手试试

let line = readLine()!

// TODO: enum ParseError; func parsePositive(_:) throws -> Int;
// 使用 do/try/catch,包含三个分支和一个兜底分支
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

逻辑与流程中的所有课

自己练习: Swift 在线编辑器