繁体   English   中英

如何在Swift 3中调用具有相关类型参数的泛型函数

[英]How to call a generic function with parameter of associated type in Swift 3

这是我的示例代码:

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'

如您所见,我使用参数定义泛型函数,该参数的类型是泛型类型 T关联类型 我怎么称呼这个功能? 我想使用MyClass.ID.one作为参数,但编译器提供以下警告:

cannot convert value of type 'MyClass.ID' to expected argument type '_.ID'

看来Swift通过从MyClass.ID开始为T.ID并且支持MyClassT从调用中推断出T是一个问题。

如果您更改函数以获取类型T的附加参数,则代码将编译并运行正常:

func process<T: B>(_ value: T.ID, _ workaround : T) {
  // do something
}

let workaround = MyClass()
process(MyClass.ID.one, workaround)

Swift设计人员可以通过两种方式解决这个推理问题:

  • 修复推理引擎以允许此用例,或
  • 通过对函数签名实施更严格的规则,使推理引擎更容易找出T

看来他们决定使用Swift 4的第二种方法,因为原始函数无法编译,发出以下错误:

通用参数'T'未在函数签名中使用

更好的解决方法是使用Java风格的方法传递类型而不是实例:

func process<T: B>(_ value: T.ID, _ workaround: T.Type) {
  // do something
}
...
process(MyClass.ID.one, MyClass.self)

注意:编辑基于tesch非常有见地的评论

dasblinkenlight为您当前实现无效的原因提供了一个很好的答案。 如果决定的解决方案是简单地找到另一种方法来实现这个功能,那么我会选择一个不那么hacky的解决方案:

extension B {
    static func process(_ value: Self.ID) {
        //do stuff
    }
}

MyClass.process(.one)

这利用了通过协议扩展Self实现的更灵活的类型推断。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM