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 用来捕获所有异常,你几乎总是需要加上它,这样编译器才不会报错。
挑战
简单定义一个枚举 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,包含三个分支和一个兜底分支
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
逻辑与流程中的所有课
自己练习: Swift 在线编辑器