通过 try 块处理 Swift 2.2 错误

Posted

技术标签:

【中文标题】通过 try 块处理 Swift 2.2 错误【英文标题】:Swift 2.2 error handling by try block 【发布时间】:2016-04-26 10:48:54 【问题描述】:

几天前我刚刚开始学习 Swift。在我的 Xcode 游乐场中,我有以下代码:

//: Playground - noun: a place where people can play

import UIKit

enum VendingMachineError: ErrorType 
    case InvalidSelection
    case InsufficientFunds(coinsNeeded: Int)
    case OutOfStock



func requestBeverage(code: Int, coins: Int) throws 
    guard code > 0 else  
        throw VendingMachineError.InvalidSelection
    
    if coins < 2 
        throw VendingMachineError.InsufficientFunds(coinsNeeded: 3)
    
    guard coins > 10 else 
        throw VendingMachineError.OutOfStock
    

    print("everything went ok")




try requestBeverage(-1, coins: 4)
print("finished...")

如果我尝试运行它,什么也不会发生。但我希望打印“完成...”,因为在我的逻辑中,它尝试做某事,失败,然后程序将继续......

所以问题是,为什么程序没有继续,以及如何用尽可能少的单词告诉代码在出错的情况下继续?

提前致谢

【问题讨论】:

是否打印了“一切正常”? 你确定是 Swift 3 吗?据我所知,Swift 3 甚至还没有处于测试阶段(它将在 WWDC 2016 之后,并且可能会在 9 月左右发布)。最有可能是 Swift 2.2(当前版本)。 苹果什么时候发布了swift 3.0?我错过了那个版本吗?请澄清我的疑问。 我明白了。我收到了 ++ deprecation 错误,所以我认为它是 3.0。但我认为你是对的。 @OWADVL 弃用意味着计划在未来版本(在本例中为 Swift 3.0)中删除某些内容,但在当前版本(Swift 2.2)中仍然可以正常工作。编译器只是警告你,你应该准备好你的代码 Swift 3.0(这样你就不会在它发布时处理大量突然的错误)。 【参考方案1】:

您可以使用 do/catch 单独捕获所有错误:

do 
    try requestBeverage(-1, coins: 4)
 catch VendingMachineError.InvalidSelection 
    print("Invalid selection")
 catch VendingMachineError.OutOfStock 
    print("Out of stock")
 catch VendingMachineError.InsufficientFunds(let coinsNeeded) 
    print("You need \(coinsNeeded) more coins")
 catch 
    // an unknown error occured


print("finished...")

或者,如果您只关心是否抛出错误而不关心哪个错误,则使用try?

func requestSomeBeverage() 
    guard (try? requestBeverage(-1, coins: 4)) != nil else 
        print("An error has occured")
        return
    


requestSomeBeverage()
print("finished...")

如果您绝对确定不会引发错误,并且希望在发生异常时引发异常,请使用try!(但在大多数情况下,不要):

try! requestBeverage(-1, coins: 4)
print("finished...")

【讨论】:

【参考方案2】:

你需要捕捉错误

... 

do 
  try requestBeverage(-1, coins: 4)
 catch 
  print(error)

print("finished...")

请参阅 Swift 语言指南中的 Error Handling

编辑:您可以将整个表达式写在一行中;-)

do  try requestBeverage(-1, coins: 4)  catch  print(error) 

【讨论】:

好的,但是您的解决方案有 6 行代码。 ...1-2 行中有什么东西吗? 实际上还有 4(!) 行。它出什么问题了?当然你可以将docatch 子句分别放在一行,但这并不能真正提高性能;-) @TimVermeulen 是的,我想这是尝试的解决方案? ...但这是正常的做法吗?或者你会写一个 do/catch... do/catch 通常是要走的路,因为它允许您catch 个别错误。如果你只关心是否抛出错误而不关心哪个错误,那么使用try? @TimVermeulen 如果你想回答我会接受的。

以上是关于通过 try 块处理 Swift 2.2 错误的主要内容,如果未能解决你的问题,请参考以下文章

Swift 2.2 HealthKit - 调用可以抛出,但它没有标有“尝试”并且错误未处理

Swift2.0:如何通过 do try catch 获取返回值和错误

Swift 异常处理

第八周动手动脑

基础C#异常处理的总结

Swift 3 中的错误处理