2017-02-26 69 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()