为了账号安全,请及时绑定邮箱和手机立即绑定

Swift do-try-catch语法

Swift do-try-catch语法

慕容708150 2019-10-24 14:22:33
我尝试理解Swift 2中新的错误处理方法。这是我做的:我首先声明了一个错误枚举:enum SandwichError: ErrorType {    case NotMe    case DoItYourself}然后我声明了一个引发错误的方法(伙计们不是异常。这是一个错误。)。这是该方法:func makeMeSandwich(names: [String: String]) throws -> String {    guard let sandwich = names["sandwich"] else {        throw SandwichError.NotMe    }    return sandwich}问题出在主叫方。这是调用此方法的代码:let kitchen = ["sandwich": "ready", "breakfeast": "not ready"]do {    let sandwich = try makeMeSandwich(kitchen)    print("i eat it \(sandwich)")} catch SandwichError.NotMe {    print("Not me error")} catch SandwichError.DoItYourself {    print("do it error")}之后,do行编译器说Errors thrown from here are not handled because the enclosing catch is not exhaustive。但我认为这是详尽无遗的,因为SandwichError枚举中只有两种情况。对于常规的switch语句,swift可以理解,在处理每种情况时,它都是详尽的。
查看完整描述

3 回答

?
哆啦的时光机

TA贡献1779条经验 获得超6个赞

Swift 2错误处理模型有两个重要方面:详尽性和弹性。它们一起归结为您的do/ catch语句,需要捕获所有可能的错误,而不仅仅是您知道可以抛出的错误。


请注意,您并未声明函数会抛出什么类型的错误,仅声明它是否会抛出任何类型的错误。这是一个零一无穷的问题:当有人为其他人(包括您将来的自己)定义一个函数供您使用时,您不需要使函数的每个客户端都适应您实现中的每个更改功能,包括可能引发的错误。您希望调用您的函数的代码能够适应这种变化。


因为您的函数无法说出它抛出的错误类型(或将来可能抛出的错误),所以catch捕获该错误的块不知道它可能抛出的错误类型。因此,除了处理您所知道的错误类型之外,您还需要使用通用catch语句来处理那些您不知道的错误类型-这样,如果您的函数更改了将来抛出的错误集,则调用方仍将捕获该错误类型。错误。


do {

    let sandwich = try makeMeSandwich(kitchen)

    print("i eat it \(sandwich)")

} catch SandwichError.NotMe {

    print("Not me error")

} catch SandwichError.DoItYourself {

    print("do it error")

} catch let error {

    print(error.localizedDescription)

}

但是,我们不要就此止步。再考虑一下这种弹性思想。设计三明治的方式必须在使用它们的每个地方描述错误。这意味着每当更改错误案例集时,都必须更改使用它们的每个位置……这不是很有趣。


定义自己的错误类型的想法是让您集中处理这样的事情。您可以description为错误定义一个方法:


extension SandwichError: CustomStringConvertible {

    var description: String {

        switch self {

            case NotMe: return "Not me error"

            case DoItYourself: return "Try sudo"

        }

    }

}

然后,您的错误处理代码可以要求您的错误类型进行自我描述-现在,您处理错误的每个地方都可以使用相同的代码,并且还可以处理将来可能发生的错误情况。


do {

    let sandwich = try makeMeSandwich(kitchen)

    print("i eat it \(sandwich)")

} catch let error as SandwichError {

    print(error.description)

} catch {

    print("i dunno")

}

这也为错误类型(或其扩展)支持其他报告错误的方式铺平了道路-例如,您可以在错误类型上具有扩展名,该扩展名知道如何呈现UIAlertController用于向iOS用户报告错误的方式。


查看完整回答
反对 回复 2019-10-24
?
繁星coding

TA贡献1797条经验 获得超4个赞

Swift担心您的case语句不能涵盖所有情况,要解决该问题,您需要创建一个默认case:


do {

    let sandwich = try makeMeSandwich(kitchen)

    print("i eat it \(sandwich)")

} catch SandwichError.NotMe {

    print("Not me error")

} catch SandwichError.DoItYourself {

    print("do it error")

} catch Default {

    print("Another Error")

}


查看完整回答
反对 回复 2019-10-24
  • 3 回答
  • 0 关注
  • 863 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信