我认为最好从一个例子开始:
class Test<T> {
func test(closure: (T) -> Void) { }
func test(closure: (T) -> T) { }
func test(closure: (T) -> Test<T>) { }
}
Test<Int>().test { a in }
上面的代码报错如下:
error: ambiguous use of 'test'
这是因为 Swift 编译器不知道应该将调用映射到三个方法中的哪一个。但是从闭包主体可以很清楚地看出它返回一个 Void
,因此它应该选择第一个方法。
看起来 Swift 编译器无法根据闭包主体确定将调用映射到哪个方法重载。如果我明确指定闭包签名,那么问题就消失了:
Test<Int>().test { (a: Int) -> Void in }
我的问题是:我能否以某种方式指示 Swift 为正在讨论的闭包表达式选择正确的重载,或者我是否必须显式声明闭包签名?
最佳答案
实际上,我似乎对编译器的限制施加了太大的压力(正如@Martin R 在评论中指出的那样)。 { a in }
闭包有点不完整,因为编译器没有语句来推断闭包返回类型。
这个有效:
Test<Int>().test { (a: Int) -> Void in () }
同上:
func doNothing() { }
Test<Int>().test { (a: Int) -> Void in doNothing() }
在上面的示例中,编译器提供了最少的信息来确定选择哪个重载。
关于swift - 使用泛型时从闭包主体推断闭包返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38888880/