Menu
CoddyTech

传递错误

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

可能抛出异常的函数可以调用其他可能抛出异常的函数。错误会自动向上传播到最近的 do/catch,无需手动重新抛出。

enum AuthError: Error { case badUser, badPass }

func loadUser(_ name: String) throws -> String {
    if name.isEmpty { throw AuthError.badUser }
    return name
}

func login(_ name: String, _ pass: String) throws -> String {
    let u = try loadUser(name)            // 将错误向上传递
    if pass.count < 4 { throw AuthError.badPass }
    return "hello \(u)"
}

do {
    print(try login("", "abcd"))
} catch AuthError.badUser {
    print("missing user")
} catch AuthError.badPass {
    print("weak password")
}

从上到下阅读:login 使用 try 调用 loadUser。如果 loadUser 抛出异常,错误会跳过 login 的函数体,转到外层的 catch。你要让每一步都快速失败,并让调用方决定接下来怎么做。

challenge icon

挑战

中等

构建一个由两个可抛出错误的步骤组成的小型流水线。

定义 StepError: Error,包含两个情况:negative、tooBig。

定义 parseSafe(_ s: String) throws -> Int:当解析出的整数小于 0 时抛出 .negative,否则返回该整数。(假设输入可以解析,你已在其他地方处理了这一点。)

定义 capStrict(_ n: Int) throws -> Int:当 n > 100 时抛出 .tooBig,否则返回 n。

定义 processStep(_ s: String) throws -> Int,先调用 parseSafe,再调用 capStrict,并让任何错误继续向上传播。

读取一行输入:一个由逗号分隔的字符串列表。对每个字符串,在 do/catch 中调用 processStep,并输出一行:

  • 成功时输出 ok: <n>
  • parseSafe 抛出错误时输出 negative
  • capStrict 抛出错误时输出 too big

输入 10,-1,200,42 时,输出为:

ok: 10
negative
too big
ok: 42

亲手试试

let parts = readLine()!.components(separatedBy: ",")

// TODO:定义枚举 StepError;实现 parseSafe、capStrict 和 processStep;
// 对每个部分,用 do/try 调用 processStep,捕获每个分支的异常并打印
quiz icon自我测试

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

逻辑与流程中的所有课

自己练习: Swift 在线编辑器