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

问题描述

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

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

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

static func getData(id: CLong,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)?是完全不同的类型,而不是同一类型的可选变体?

解决方法

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

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

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

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

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...