具有泛型的Swift函数,其中约束是自身符合的协议

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了具有泛型的Swift函数,其中约束是自身符合的协议相关的知识,希望对你有一定的参考价值。

我正在尝试编写一个静态泛型方法,该方法将协议作为参数并在Swinject容器中注册类实例作为协议解析。重要的是我无法将模块注册为不符合的协议。

我写了这样的东西:

/// RegisterableModule guarantee that conformer has `create()` method returning self

public extension RegisterableModule {

    static func registerModule<P>(asProtocol proto: P.Type,
                                  in container: Container) {
        container.register(proto, name: nil) { (resolver) -> P in
            return self.create()
        }
    }
}

它没有编译,因为显然Self可能不符合P.

我还尝试使用where指定泛型约束:

  1. where Self: P编译错误“类型'自我'约束到非协议,非类型'P'”
  2. where self: P做多次编译错误。
  3. where Self: P.Type确实编译错误“类型'自我'约束到非协议,非类型''P.Type'”
  4. where self: P.Type做了多个编译错误。

我也想知道我是否可以指定P只能作为协议的约束。

答案

不幸的是,Swift没有办法定义对通用参数的一致性要求,或者要求参数是一个协议。

这就是为什么Swinject的类型转发API is not type safe。有一个"trick"可以让人们表达一致性要求,但是我不确定它是否适用于你的用例:

extension RegisterableModule {

    static func registerModule<P>(
        asProtocol proto: P.Type, 
        in container: Container, 
        typeCheck: (Self) -> P
    ) {
        container.register(proto) { _ in self.create() as! P }
    }
}

MyModule.registerModule(
    asProtocol: MyProtocol.self, 
    in: container, 
    typeCheck: { $0 }
)
另一答案

你能尝试一下,我刚刚添加了P:SomeProtocol

public extension RegisterableModule {

    static func registerModule<P:SomeProtocol>(asProtocol proto: P.Type,
                                  in container: Container) {
        container.register(proto, name: nil) { (resolver) -> P in
            return self.create()
        }
    }
}

以上是关于具有泛型的Swift函数,其中约束是自身符合的协议的主要内容,如果未能解决你的问题,请参考以下文章

Swift参数及泛型参数参考!

Swift:检查泛型类型是不是符合协议

打字稿中具有泛型的子类型约束

Swift 泛型和协议扩展

符合 Swift 协议的泛型类型

Swift 3 扩展限制为一个类型