为什么不可能将`(()-> Void)`转换为`(()-> Void)`?

时间:2020-09-10 04:59:10

标签: ios swift lambda

我有一个接受请求的函数和一个用于服务器响应的可选回调:

static func getData(request: NSMutableDictionary?, callback: ((Dictionary<String, Any>) -> Void)? ) {
    // ...
}

我想为此函数编写一个包装,其中参数不是可选的。我是这样做的:

static func getData(id: CLong, callback: ((Dictionary<String, Any>) -> Void) ) {
    getData(request: ["userId" : id], callback: callback)
}

问题是swift无法将类型((Dictionary<String, Any>) -> Void)转换为类型((Dictionary<String, Any>) -> Void)?。我不知道为什么。毕竟,我们可以成功地将非可选转换为可选:

var a = "hello"
var b: String? = a // correct

为什么不能迅速做到这一点?为什么Swift会认为类型((Dictionary<String, Any>) -> Void)和类型((Dictionary<String, Any>) -> Void)?是完全不同的类型,而不是同一类型的可选变体?

1 个答案:

答案 0 :(得分:3)

当一个闭包被包装在一个可选包中时,该闭包会“转义”。如果您不知道“转义”是什么意思,请阅读this answer of mine

第二个getData中的非可选闭包不是@escaping。因此,您正在尝试进行转义的转义!该错误消息在这里有点令人困惑,但是如果您直接通过.some(callback)而不是callback,则很清楚发生了什么:

将非转义参数“ callback”转换为通用参数“ Wrapped”可能会使其逃脱

因此,您应在第二个callback中将getData标记为@escaping

func getData(id: CLong, callback: @escaping ((Dictionary<String, Any>) -> Void) ) {
相关问题