这是我的示例代码:
protocol P {
}
protocol B {
associatedtype ID: P
}
class MyClass: B {
enum ID: P {
case one
case two
}
}
func process<T: B>(_ value: T.ID) {
// do something
}
process(MyClass.ID.one) // Compile Error: cannot convert value of type 'MyClass.ID' to expected argument type '_.ID'
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,我定义与它的类型是一个参数,一个泛型函数相关类型的的泛型类型 牛逼.我怎么称呼这个功能?我想使用MyClass.ID.one作为参数,但编译器提供以下警告:
cannot convert value of type 'MyClass.ID' to expected argument type '_.ID'
Run Code Online (Sandbox Code Playgroud)
看起来,Swift T从调用中推断出一个问题,从MyClass.ID存在开始,T.ID然后回归到MyClass存在T.
如果更改函数以获取类型的附加参数T,则代码将编译并运行正常:
func process<T: B>(_ value: T.ID, _ workaround : T) {
// do something
}
let workaround = MyClass()
process(MyClass.ID.one, workaround)
Run Code Online (Sandbox Code Playgroud)
Swift设计人员可以通过两种方式解决这个推理问题:
T通过对函数签名实施更严格的规则,使推理引擎更容易理解.看来他们决定使用Swift 4的第二种方法,因为原始函数无法编译,发出以下错误:
泛型参数
'T'未在函数签名中使用
更好的解决方法是使用Java风格的方法传递类型而不是实例:
func process<T: B>(_ value: T.ID, _ workaround: T.Type) {
// do something
}
...
process(MyClass.ID.one, MyClass.self)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2334 次 |
| 最近记录: |