【问题标题】:try, try! & try? what’s the difference, and when to use each?试试! & 尝试?有什么区别,什么时候使用?
【发布时间】:2015-11-30 04:08:44
【问题描述】:

Swift 2.0 中,Apple 引入了一种处理错误的新方法(do-try-catch)。 几天前,在 Beta 6 中引入了一个更新的关键字 (try?)。 另外,知道我可以使用try!。 这 3 个关键字有什么区别,何时使用?

【问题讨论】:

    标签: swift error-handling swift3 swift2


    【解决方案1】:

    为 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()
    }

    试试吧!

    当你尝试访问一个隐式解包的可选选项时会发生什么?是的,没错,应用程序会崩溃! 试试也一样!它基本上忽略了错误链,并声明了“做或死”的情况。如果调用的函数没有抛出任何错误,则一切正常。但如果它失败并抛出错误,您的应用程序将简单地崩溃

    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
    

    【讨论】:

    • 您的第二个代码示例 (let result = try doSomething() // Not within a do-catch block) 将从声明为 throws 的方法中调用,对吗?那么,如果doSomething() 失败了,那么外部方法也会(反过来)吗?
    • 在 swift 4 中,试试?不会删除在我的项目中的“尝试”表达式中发生的对抛出函数的不调用。
    • 您也可以将try??? 一起使用,这样您就可以在一行中定义一个默认值:let something:String = (try? whateverIfItThrows()) ?? "Your default value here"
    • 有谁记不住试试! vs试试? vs 尝试,然后一次又一次地在这里结束......这可能是语言臃肿的标志?
    • @BenButterworth 老实说不是,只要你记得只有 try 必须包含在 do-catch 中,而其他两个不需要,那么你就可以认识到 !? 有效作为标准的可选运算符。
    猜你喜欢
    • 1970-01-01
    • 2012-12-03
    • 2021-07-14
    • 2011-09-19
    • 1970-01-01
    • 2019-11-24
    • 1970-01-01
    • 2011-07-15
    • 1970-01-01
    相关资源
    最近更新 更多