在Swift 2.0中,Apple 引入了一种处理错误的新方法(do-try-catch)。几天前,在 Beta 6 中引入了一个更新的关键字 ( try?)。另外,知道我可以使用try!. 3 个关键字之间有什么区别,以及何时使用每个关键字?
try?
try!
为 Swift 5.1 更新
假设以下抛出函数:
enum ThrowableError: Error { case badError(howBad: Int) } func doSomething(everythingIsFine: Bool = false) throws -> String { if everythingIsFine { return "Everything is ok" } else { throw ThrowableError.badError(howBad: 4) } }
当您尝试调用可能抛出的函数时,您有 2 个选项。
您可以通过在 do-catch 块中包围您的调用来负责 处理错误:
do { let result = try doSomething() } catch ThrowableError.badError(let howBad) { // Here you know about the error // Feel free to handle or to re-throw // 1. Handle print("Bad Error (How Bad Level: \(howBad)") // 2. Re-throw throw ThrowableError.badError(howBad: howBad) }
或者只是尝试调用该函数,并将 错误传递 给调用链中的下一个调用者:
func doSomeOtherThing() **_throws_** -> Void { // Not within a do-catch block. // Any errors will be re-thrown to callers. let result = try doSomething() }
当您尝试访问其中包含 nil 的隐式展开的可选项时会发生什么?是的,没错,应用程序会崩溃!试试也一样!它基本上忽略了错误链,并声明了“要么失败”的情况。如果被调用的函数没有抛出任何错误,一切正常。但是如果它失败并抛出错误, 你的应用程序就会崩溃 。
let result = try! doSomething() // if an error was thrown, CRASH!
Xcode 7 beta 6 中引入的一个新关键字。它 返回一个可 解包成功值的可选项,并通过返回 nil 来捕获错误。
if let result = try? doSomething() { // doSomething succeeded, and result is unwrapped. } else { // Ouch, doSomething() threw an error. }
或者我们可以使用守卫:
guard let result = try? doSomething() else { // Ouch, doSomething() threw an error. } // doSomething succeeded, and result is unwrapped.
最后一个注释,通过使用try?注释,您将丢弃发生的错误,因为它转换为 nil。使用试试?当你更多地关注成功和失败,而不是事情失败的原因时。
您可以使用合并运算符 ?? 试试?在失败的情况下提供默认值:
let result = (try? doSomething()) ?? "Default Value" print(result) // Default Value