2017-05-12 62 views
2

使用函數throws時,我們使用do-catch來處理可能的錯誤。假設我們正在編寫一個函數,並且我們希望該函數傳播錯誤:Swift 3 - 完成並投擲

public func myFunc() throws 
{ 
    do 
    { 
     let obj = try convert(param: 42) 
     // work with obj... 
    } 
    catch 
    { 
     print("failed: \(String(describing: error))") 
     throw MyError.ConversionFailed 
    } 
} 

這很好。但是,現在讓我們說我們有myFunc定製邏輯可能導致函數拋出不同類型的錯誤:

public func myFunc() throws 
{ 
    do 
    { 
     let obj = try convert(param: 42) 
     // work with obj... 
     if obj is Array 
     { 
      // great, continue working with obj... 
     } 
     else 
     { 
      throw MyError.NotAnArray 
     } 
    } 
    catch 
    { 
     print("failed: \(String(describing: error))") 
     throw MyError.ConversionFailed 
    } 
} 

但是,這是行不通的:內throwdo-catch被捕獲並myFunc將只拋出錯誤ConversionFailed,而不是NotAnArray錯誤。使這一工作

一種方法是:

public func myFunc() throws 
{ 
    do 
    { 
     let obj = try convert(param: 42) 
     // work with obj... 
     if obj is Array 
     { 
      // great, continue working with obj... 
     } 
     else 
     { 
      throw MyError.NotAnArray(object: obj) 
     } 
    } 
    catch MyError.NotAnArray(let obj) 
    { 
     throw MyError.NotAnArray(object: obj) 
    } 
    catch 
    { 
     print("failed: \(String(describing: error))") 
     throw MyError.ConversionFailed 
    } 
} 

這樣的作品,但似乎重複的,尤其是當有關聯的值,如果自定義邏輯是複雜的,我可能需要幾個catch ES。有沒有更好的方法來做到這一點?

回答

1

如果您想用另一個錯誤替代convert() 拋出的錯誤,請在本地do/catch上下文中調用convert()。 不需要外部do/catch,因爲 投擲函數「自動」將錯誤向上傳播給調用者(比較How to pass an Error up the stack trace in Swift) 。

public func myFunc() throws 
{ 
    let obj: Any // or whatever type convert() returns 
    do { 
     obj = try convert(param: 42) 
    } catch { 
     throw MyError.ConversionFailed 
    } 
    // work with obj... 
    if obj is Array { 
     // great, continue working with obj... 
    } else { 
     throw MyError.NotAnArray 
    } 
} 
+0

謝謝馬丁,你是對的。自動傳播也是一個好點,我不知道。但是如果我改變自己的意圖拋出自定義錯誤而不是重新拋出同一個錯誤呢? – Stephenye

+0

@Stephenye:你的意思是用自定義錯誤代替'aFunctionThatThrows()'拋出的錯誤?在這種情況下,你必須在本地的do/catch上下文中調用該函數。 –

+0

是的,我更新了這個問題以更好地說明我的意思。我想我需要在這種情況下再捕捉一次嗎? – Stephenye