我正在尝试将我的代码从xcode 8.2 swift 3.0.2迁移到xcode 9 swift 4,并且我对此代码有疑问:
I am trying to migrate my code from xcode 8.2 swift 3.0.2 to xcode 9 swift 4, and I have problem with this code:
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,使用以下命令即可快速获得3.0.2结果:
xcode 8.0.2, swift 3.0.2 results with:
foo2 Int Intxcode 9,使用以下命令快速获得4条结果
xcode 9, swift 4 results with:
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中是否有任何新功能会导致此错误?
Am I missing something? Is there any new feature in swift 4 that causes this error?
我按照评论中的建议在bugs.swift中提交了一个错误. bugs.swift/browse/SR-6108
I filed a bug at bugs.swift as suggested in the comments. bugs.swift/browse/SR-6108
推荐答案我遇到了同样的问题,偶然发现了一种解决方法(出于我的目的)比通过命名消除歧义更好.也许这还不是解决方法,而仅仅是必须采取的方式.
I ran into the same problem, and stumbled across a workaround that is (for my purposes) nicer than disambiguating via naming. Perhaps it is not even a workaround, just the way things have to be. It's also possible that this is newly-possible in Swift 4.1 (not sure, since I migrated directly from Swift 3 to 4.1)
更改此:
func test< T0,TRet>(fn:(T0)-> TRet)->无效
...对此...
func test< T0,TRet>(fn:((T0))-> TRet)->无效
(请注意在 T0 回调参数周围的额外一对括号,这将使它显式地变成1元组)
(note the extra pair of parens around the T0 callback parameter, which explicitly makes it into a tuple-of-1)
此更改之后, test(fn2 )编译并调用 test< T0,T1,TRet> 重载.似乎编译器能够将具有N个参数的函数视为具有一个N向元组参数的函数.因此,(T0)->TRet 和(T0,T1)->TRet 重载是fn2的候选对象,并且该调用不明确.添加第二对括号((T0))->TRet 将重载限制为具有单个参数或1路元组的参数.
After this change, test(fn2) compiles and calls the test<T0,T1,TRet> overload. It seems that the compiler is able to treat a function with N arguments as a function with one N-way-tuple argument. Hence, both the (T0) -> TRet and (T0,T1) -> TRet overloads are candidates for fn2, and the call is ambiguous. Adding 2nd pair of parens ((T0)) -> TRet limits that overload to an argument with a single parameter or 1-way tuple.
更多推荐
“歧义使用"指的是:迁移到swift后的通用方法4
发布评论