"模糊使用"迁移到swift 4后的泛型方法

时间:2017-10-09 14:42:20

标签: swift generics xcode9 swift4

我正在尝试将我的代码从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

1 个答案:

答案 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路元组的参数。