具有泛型的Swift功能,其中约束是一个自我遵循的协议

时间:2019-02-22 08:15:57

标签: ios swift generics protocols swinject

我正在尝试编写一个静态通用方法,该方法将协议作为参数并在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()
        }
    }
}

它无法编译,因为很明显,自我可能不符合P

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

  1. where Self: P确实编译错误“类型为'Self'的类型限制为非协议,类型为'P'的非

  2. where self: P发生多次编译错误。
  3. where Self: P.Type确实编译错误“类型'Self'被限制为非协议,非类类型'P.Type'”
  4. where self: P.Type发生多个编译错误。

我还想知道是否可以指定一个约束,即P只能是协议。

2 个答案:

答案 0 :(得分:1)

不幸的是,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 }
)

答案 1 :(得分: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()
        }
    }
}