这是一个示例游乐场:
protocol P { associatedtype T func getValue() -> T } class Foo: P { func getValue() -> String { return "hello" } } class Bar { func test<T: P>(_ o: T) { print("Generic",o.getValue()) } func test(_ o: Any) { print("Any") } } let foo = Foo() let bar = Bar() bar.test(foo)
这输出:任何.
如果我删除任何版本的测试,则调用泛型方法.
Foo类符合协议P,为什么Swift不选择泛型方法,因为它更具体?有没有办法调用通用的?
解决方法
据我所知,编译器在执行重载解析时总是倾向于使用显式类型参数而不是通用类型参数.因此,在测试< T:P>(_ o:T)和test(_ o:Any)之间的分辨率中 – 后者将是首选的,因为它具有显式(尽管是抽象的)参数类型,而第一个仅仅是占位符.
因此,如果您使第二个重载也是通用的,编译器现在将支持第一个重载,因为它们都没有显式类型化参数,但第一个重载受到更严格的限制:
class Bar { func test<T: P>(_ o: T) { print("Generic",o.getValue()) } func test<T>(_ o: T) { print("Any") } } let foo = Foo() let bar = Bar() bar.test(foo) // Generic hello
保持过载原样,为了消除歧义,类型转换似乎也是一个可行的解决方案:
class Bar { func test<T: P>(_ o: T) { print("Generic",o.getValue()) } func test(_ o: Any) { print("Any") } } let foo = Foo() let bar = Bar() (bar.test as (Foo) -> Void)(foo) // Generic hello
虽然我强烈建议使用第一种方法,因为它允许您更好地推断将选择什么样的过载(一般情况下,泛型也应该优先于协议类型的参数,due to the performance benefits of specialisation).
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。