【问题标题】:Throw from a trailing closure in Swift从 Swift 的尾随闭包中抛出
【发布时间】:2020-10-09 09:43:27
【问题描述】:

我正在做一些网络工作,想根据响应从尾随闭包中抛出。

因此,我发现由于“无效转换”错误而无法执行此操作。

我已将问题简化为一个最小示例 - 不允许陈词滥调:

func innerClosure(a: String, completion: (String)->Void) {
    completion(a + ", World")
}

func iCanThrow(name: String, closure: (String,(String)->Void)->(Void) ) throws {
     closure(name, {response in
        print (response)
        if response == "Hello, World" {
            throw ClicheError.cliche
        }
    })

}

try iCanThrow(name: "Hello", closure: innerClosure)

你可以看到我想从尾随闭包中抛出一个ClicheError - 但具体错误是Invalid conversion from throwing function of type '(String) throws -> Void' to non-throwing function type '(String) -> Void'

我尝试过使用 throwsrethrows 的各种组合,但我根本无法让它工作 - 即使我得到 throw 的内部封闭,我得到以下信息:

enum ClicheError: Error {
    case cliche
    case latecliche
}

func innerClosure(a: String, completion: (String) throws ->Void) {
    try? completion(a + ", World")
}

func iCanThrow(name: String, closure: (String,(String) throws ->Void) throws ->(Void) ) throws {
     try closure(name, {response in
        print (response)
        if response == "Hello, World" {
            throw ClicheError.cliche
        }
    })

}

try iCanThrow(name: "Hello", closure: innerClosure)

iCanThrow 编译、抛出但实际上并没有抛出——这意味着我不能抛出!

【问题讨论】:

标签: swift


【解决方案1】:
func innerClosure(a: String, completion: (String) throws ->Void) {
    try? completion(a + ", World")
}

不会抛出错误,因为try? 是一个“可选尝试”:它返回一个Optional,如果出现错误,它就是nil。这里的返回值被忽略了,所以错误被默默地忽略了。

你想要的是

func innerClosure(a: String, completion: (String) throws ->Void) rethrows {
    try completion(a + ", World")
}

这使得 innerClosure() 只有在使用 throwing 参数调用时才成为 throwing 函数。

func iCanThrow() 也可以标记为 rethrows 而不是 throws,因为它不会“自行”引发错误。 另见What are the differences between throws and rethrows in Swift?

【讨论】:

    猜你喜欢
    • 2018-03-27
    • 1970-01-01
    • 1970-01-01
    • 2019-08-14
    • 1970-01-01
    • 2019-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多