2017-02-26 47 views
1
  • 为什么我需要为do-try-catch提供一般的catch语句,即使我确定我的自定义错误只是在do-try-catch语句中抛出?
  • 而且,为什么Xcode Project和Playground的行为不同?

我试图在我的iOS应用程序中使用一个简单的Swift的do-try-catch错误。Xcode Project和Playground之间关于Swift错误处理的区别

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语句已经是不一般的抓详尽,但似乎我需要添加它。

即使奇怪的是,当我运行在游乐场此代码不需要一般catch声明。

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

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

回答

1

如果你读过的雨燕语言指导彻底,之所以出现这种情况的原因并不难找。

让我们看看语言是怎么说的:

的catch子句不必处理每一个可能的错误,它做子句中的代码可以抛出。 如果没有任何catch子句处理该错误,则错误会传播到周围的范围。但是,错误必须由一些周围的作用域处理 - 或者通过封闭的处理错误的do-catch子句或通过位于抛出函数中。

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

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

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

基本上,全局范围为您处理所有事情。即使眼前这个编译:

try fooFunc()