具有泛型基类的泛型类型的重写属性

时间:2019-03-21 09:21:29

标签: swift generics inheritance

这就是我想要做的:

rewrite

在行/swagger/index.html?url=/swagger/v1/swagger.json上,我遇到了一个错误protocol GenericFactory { associatedtype Input associatedtype Value func create(with input: Input) -> Value } class Base<Factory: GenericFactory> { var input: Factory.Input { preconditionFailure("To be overriden") } } protocol ValueProtocol {} struct SomeInputImpl {} protocol ValueFactory: GenericFactory where Input == SomeInputImpl, Value: ValueProtocol {} class Child<Factory: ValueFactory>: Base<Factory> { override var input: Factory.Input { return SomeInputImpl() } } 。我不了解此错误的原因,因为swift override var input: Factory.Input {协议中描述了输入类型,但是由于某些原因,swift会将base中的Factory.Input和Child中的Factory.input解释为不同的类型。有人可以解释一下这是怎么回事吗?

2 个答案:

答案 0 :(得分:2)

仅是为了完成有关在Swift 5中解决此问题的要点,以下是在您的示例代码中将在Swift 5中有效的演示,但不适用于Swift 4.2。

struct Val: ValueProtocol {}

struct VF: ValueFactory {
    func create(with input: SomeInputImpl) -> Val {
        return Val()
    }
}

let child = Child<VF>()
child.input  // SomeInputImpl

但是,几乎可以肯定,使用函数而不是使用GenericFactory会更好。使用Factory模式的主要原因是要处理缺少高阶函数和一流类型的语言,例如Java 8之前的版本。在具有高阶函数和一流类型的语言(例如Swift)中,通常不需要使用Factory模式。您可以直接直接传递函数(Input) -> Value

您的示例没有显示调用方,因此很难确切地知道哪种基于函数的解决方案最有效,但是在大多数情况下,泛型函数比协议+ associatedType +泛型+继承更好。特别是,将类继承混合到关联类型中会使您陷入困境(因为关联类型和类继承在某种程度上是正交的多态方法)。

答案 1 :(得分:0)

protocol ValueFactory: GenericFactory where Input: SomeInputImpl, Value: ValueProtocol {}

输入应确认SomeInputImpl。 由于SomeInputImpl是结构类型,因此无法继承。所以你必须使其成为类或协议

class SomeInputImpl {}

然后您可以覆盖输入变量

class Child<Factory: ValueFactory>: Base<Factory> {
override var input: Factory.Input {
    return SomeInputImpl() as! Factory.Input
}

}