Swift do-try-catch语法 [英] Swift do-try-catch syntax

查看:151
本文介绍了Swift do-try-catch语法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试尝试快速了解2中新的错误处理内容.这是我所做的:我首先声明了一个错误枚举:

I give it a try to understand new error handling thing in swift 2. Here is what I did: I first declared an error enum:

enum SandwichError: ErrorType {
    case NotMe
    case DoItYourself
}

然后我声明了一个引发错误的方法(伙计们不是一个异常.这是一个错误.).这是该方法:

And then I declared a method that throws an error (not an exception folks. It is an error.). Here is that method:

func makeMeSandwich(names: [String: String]) throws -> String {
    guard let sandwich = names["sandwich"] else {
        throw SandwichError.NotMe
    }

    return sandwich
}

问题出在呼叫方.这是调用此方法的代码:

The problem is from the calling side. Here is the code that calls this method:

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枚举中只有两种情况.

After the do line compiler says Errors thrown from here are not handled because the enclosing catch is not exhaustive. But in my opinion it is exhaustive because there is only two case in SandwichError enum.

对于常规的switch语句,swift可以理解,在处理每种情况时,它都是详尽无遗的.

For regular switch statements swift can understands it is exhaustive when every case handled.

推荐答案

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

There are two important points to the Swift 2 error handling model: exhaustiveness and resiliency. Together, they boil down to your do/catch statement needing to catch every possible error, not just the ones you know you can throw.

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

Notice that you don't declare what types of errors a function can throw, only whether it throws at all. It's a zero-one-infinity sort of problem: as someone defining a function for others (including your future self) to use, you don't want to have to make every client of your function adapt to every change in the implementation of your function, including what errors it can throw. You want code that calls your function to be resilient to such change.

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

Because your function can't say what kind of errors it throws (or might throw in the future), the catch blocks that catch it errors don't know what types of errors it might throw. So, in addition to handling the error types you know about, you need to handle the ones you don't with a universal catch statement -- that way if your function changes the set of errors it throws in the future, callers will still catch its errors.

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

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

But let's not stop there. Think about this resilience idea some more. The way you've designed your sandwich, you have to describe errors in every place where you use them. That means that whenever you change the set of error cases, you have to change every place that uses them... not very fun.

定义自己的错误类型的想法是让您集中处理类似的事情.您可以定义

The idea behind defining your own error types is to let you centralize things like that. You could define a description method for your errors:

extension SandwichError: CustomStringConvertible {
    var description: String {
        switch self {
            case NotMe: return "Not me error"
            case DoItYourself: return "Try sudo"
        }
    }
}

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

And then your error handling code can ask your error type to describe itself -- now every place where you handle errors can use the same code, and handle possible future error cases, too.

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用户错误.

This also paves the way for error types (or extensions on them) to support other ways of reporting errors -- for example, you could have an extension on your error type that knows how to present a UIAlertController for reporting the error to an iOS user.

这篇关于Swift do-try-catch语法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆