Swift 3 - do-catch和throw

3

在处理会抛出异常的函数时,我们使用do-catch语句来处理可能出现的错误。假设我们正在编写一个函数,并希望该函数传播错误:

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
    }
}

但这样行不通:内部的throw将被do-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。有更好的方法吗?

1个回答

1
如果您想用另一个错误替换由convert()抛出的错误,则需要在本地do/catch上下文中调用convert()。外部do/catch不是必需的,因为抛出异常的函数会自动将错误传播给调用者(请参见如何在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
    }
}

谢谢Martin,你说得对。自动传播也是一个很好的观点,我不知道。但是如果我改变我的意图,抛出一个自定义错误而不是重新抛出相同的错误呢? - Stephenye
@Stephenye:你的意思是用自定义错误替换aFunctionThatThrows()抛出的错误吗?在这种情况下,您必须在本地do/catch上下文中调用该函数。 - Martin R
是的,我更新了问题以更好地说明我的意思。那么我想在这种情况下需要另一个catch语句,对吗? - Stephenye
@Stephenye:请查看更新的答案,希望那是你所寻找的。 - Martin R

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接