Arn*_*nol 5 generics overloading swift
这是一个示例游乐场:
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)
Run Code Online (Sandbox Code Playgroud)
这输出:Any.
如果我删除Any版本test,则调用泛型方法.类Foo符合协议P,为什么Swift不选择泛型方法,因为它更具体?有没有办法调用通用的?
据我了解,在执行重载解析时,编译器总是倾向于使用显式类型参数而不是泛型参数。test<T : P>(_ o: T)因此,在和\xe2\x80\x93之间的解析中,test(_ o: Any)后者将是首选,因为它具有显式(尽管是抽象)参数类型,而第一个只是占位符。
因此,如果您也将第二个重载设为泛型,编译器现在将支持第一个重载,因为它们都没有显式类型化参数,但第一个重载受到更严格的约束:
\n\nclass Bar {\n func test<T: P>(_ o: T) {\n print("Generic", o.getValue())\n }\n\n func test<T>(_ o: T) {\n print("Any")\n }\n}\n\nlet foo = Foo()\nlet bar = Bar()\nbar.test(foo) // Generic hello\nRun Code Online (Sandbox Code Playgroud)\n\n保持重载不变,通过类型转换来消除歧义似乎也是一个可行的解决方案:
\n\nclass Bar {\n func test<T: P>(_ o: T) {\n print("Generic", o.getValue())\n }\n\n func test(_ o: Any) {\n print("Any")\n }\n}\n\nlet foo = Foo()\nlet bar = Bar()\n(bar.test as (Foo) -> Void)(foo) // Generic hello\nRun Code Online (Sandbox Code Playgroud)\n\n尽管我强烈推荐第一种方法,因为它可以让您更好地推断将选择什么重载(由于专业化的性能优势,通常也应该尽可能优先于协议类型参数)。
\n| 归档时间: |
|
| 查看次数: |
462 次 |
| 最近记录: |