关于Swift错误处理的Xcode Project和Playground之间的区别

时间:2017-02-26 19:47:14

标签: ios swift xcode error-handling swift-playground

  • 为什么我需要为do-try-catch提供一般catch语句,即使我确定我的自定义错误只是在do-try-catch语句中抛出?
  • 并且,为什么Xcode Project和Playground之间的行为有所不同?

我试图在我的iOS应用程序中使用一个简单的Swift的do-try-catch错误。

enum FooError: Error {
    case foo
}

func fooFunc() throws {
    throw FooError.foo
}

当我调用此函数时,我试图仅捕获FooError.foo错误。

override func viewDidLoad() {
    super.viewDidLoad()

    do {
        try fooFunc()
    } catch FooError.foo {
        print("foo error is thrown.")
    }
}

但这有一个编译错误"Errors thrown from here are not handled because the enclosing catch is not exhaustive"

抛出此编译错误的原因是我的catch语句不够,我可以通过添加常规catch语句来修复此错误。

override func viewDidLoad() {
    super.viewDidLoad()

    do {
        try fooFunc()
    } catch FooError.foo {
        print("foo error is thrown.")
    } catch {
        print("something else wrong happened. \(error)")
    }
}

我认为fooFunc只会抛出FooError,所以catch语句已经详尽无需一般捕获,但似乎我需要添加它。

即使是奇怪的是,当我在Playground上运行此代码时,不需要通用的catch语句。

do {
    try fooFunc()
} catch FooError.foo {
    print("foo error is thrown.")
}

我想知道为什么Xcode Project和Playground之间的错误处理行为不同。

1 个答案:

答案 0 :(得分:2)

如果你曾经仔细阅读过Swift语言指南,那么就不难发现这种情况。

让我们看一下语言指南的内容:

  

catch子句不必处理其do子句中的代码可能抛出的每个可能的错误。 如果没有catch子句处理错误,则错误会传播到周围的范围。但是,错误必须由某些周围的范围处理 - 通过处理错误的封闭do-catch子句或通过进入投掷功能。

看到粗体部分?无论发生什么,必须处理各种错误,可能不在catch子句中,但必须在某处处理。如果您未在catch子句中处理,则需要将封闭方法标记为throws或使用try?try!

您在游乐场中运行的代码没有任何封闭范围。您正在全球范围内编写代码。全局范围处理错误的方式就是崩溃。尝试在操场上运行此代码。它不编译:

func a() {
    do {
        try fooFunc()
    } catch FooError.foo {
        print("foo error is thrown.")
    }
}

基本上,全球范围为您处理一切。即便只是编译:

try fooFunc()