我正在尝试将我的代码从xcode 8.2 swift 3.0.2迁移到xcode 9 swift 4,我对此代码有疑问:
func test<T0, TRet>(_ fn: (T0) -> TRet) -> Void {
print("foo1")
print(T0.self)
}
func test<T0, T1, TRet>(_ fn: (T0, T1) -> TRet) -> Void {
print("foo2")
print(T0.self)
print(T1.self)
}
let fn2 : (Int, Int) -> Int = { (x:Int, y:Int)->Int in
return x+y
}
test(fn2)
xcode 8.0.2,swift 3.0.2结果:
foo2
Int
Int
xcode 9,swift 4结果:
Playground execution failed:
error: MyPlayground.playground:12:1: error: ambiguous use of 'test'
test(fn2)
^
MyPlayground.playground:1:6: note: found this candidate
func test<T0, T1, TRet>(_ fn: (T0, T1) -> TRet) -> Void {
^
我错过了什么吗? swift 4中是否有任何新功能导致此错误?
我根据评论中的建议在bugs.swift.org上提交了一个错误 https://bugs.swift.org/browse/SR-6108
答案 0 :(得分:0)
我遇到了同样的问题,偶然发现了一种解决方法(出于我的目的)比通过命名消除歧义更好。也许这还不是解决方法,而仅仅是必须采取的方式。
在Swift 4.1中这可能是新可能的(不确定,因为我直接从Swift 3迁移到4.1)更改此:
func test<T0, TRet>( fn: (T0) -> TRet) -> Void
...对此...
func test<T0, TRet>( fn: ((T0)) -> TRet) -> Void
(请注意T0
回调参数周围的一对多余的括号,这将其明确地变成1元组)
此更改之后,test(fn2
)编译并调用test<T0,T1,TRet>
重载。
似乎编译器能够将具有N个参数的函数视为具有一个N-way-tuple参数的函数。因此,(T0) -> TRet
和(T0,T1) -> TRet
重载都是fn2的候选,并且调用是模棱两可的。添加第二对括号((T0)) -> TRet
可以将重载限制为具有单个参数或1路元组的参数。