2017-05-12 35 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