“歧义使用"指的是:迁移到swift后的通用方法4 [英] "ambiguous use" on generic method after migration to swift 4

查看:56
本文介绍了“歧义使用"指的是:迁移到swift后的通用方法4的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

xcode 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.org中提交了一个错误.
https://bugs.swift.org/browse/SR-6108

I filed a bug at bugs.swift.org as suggested in the comments.
https://bugs.swift.org/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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆