更改符合' SequenceType'的类的子类的' generate()' -method。

时间:2015-02-03 15:40:39

标签: class swift subclass generator sequence

我们假设我有一个泛型类 Parent<P>,它符合SequenceType 协议,通过实现{{ 1}} 方法

generate()

现在,class Parent<P> { //... } extension Parent: SequenceType { func generate() -> GeneratorOf<[P]> { //... return GeneratorOf<[P]> { //return the next element, or nil to stop } } 方法显然不会返回generate()类型的元素,而是P

现在让我们实现一个子类[P]

Child<C>

class Child<C>: Parent<C> { //... } 也应符合Child,但不应返回SequenceType类型的元素,而应返回[C]
从逻辑上讲,我尝试实现自己的C方法:

generate()

虽然这不起作用,但swift会抛出错误:

extension Child: SequenceType {
    func generate() -> GeneratorOf<C> {
    //...

    return GeneratorOf<C> {
        //return the next element, or nil to stop
    }
}

这里有什么问题,我该如何解决?


更新#1:

所以问题似乎是通过应用@ rintaro的方法来解决的,该方法仅在<stdin>: error: type 'Child<C>' does not conform to protocol '_Sequence_Type' extension Child: SequenceType { ^ Swift._Sequence_Type: note: multiple matching functions named 'generate()' with type '() -> Child<C>.Generator' func generate() -> Generator ^ <stdin>: note: candidate exactly matches [with Generator = GeneratorOf<C>] func generate() -> GeneratorOf<C> { ^ <stdin>: note: candidate exactly matches [with Generator = GeneratorOf<[C]>] func generate() -> GeneratorOf<[P]> { ^ <stdin>: error: type 'Child<C>' does not conform to protocol 'SequenceType' extension Child: SequenceType { ^ Swift.SequenceType: note: multiple matching functions named 'generate()' with type '() -> Child<C>.Generator' func generate() -> Generator ^ <stdin>: note: candidate exactly matches [with Generator = GeneratorOf<C>] func generate() -> GeneratorOf<C> { ^ <stdin>: note: candidate exactly matches [with Generator = GeneratorOf<[C]>] func generate() -> GeneratorOf<[P]> { 中为typealias定义Generator
但正如@AirspeedVelocity和@NateCook在评论中所讨论的那样,这不是一种非常可行的方法,因为Child 也可以被子类化。

还有人说可以创建一个实例属性计算我假设)返回所需元素的序列

Child

实例仍可用于 for-in-loops

class Parent<P> {
    var asSequence: [[P]] {
        //some kind of getter
    }

    //...
}

class Child<C>: Parent<C> {
    override var asSequence: [C] {
        //some kind of getter
    }

    //...
}

这会是&#34;最好的&#34; 方法吗?

更新#1.1:

正如@MichaelWelch建议的那样,属性for element in someParent.asSequence { //element is of type [P] } for element in someChild.asSequence { //element is of type C } )的名称在这种情况下可能会引起混淆,因为它们会返回不同的类型。
这似乎是合适的,但取决于具体情况。但通常应该避免模棱两可。

1 个答案:

答案 0 :(得分:2)

看来,你可以。只有<{strong> GeneratorChild 的明确类型才有效。但是,我也认为你不应该这样做......

class Parent<P> {
    var _src:[[P]] = []
}

extension Parent: SequenceType {

    func generate() -> GeneratorOf<[P]> {

        var g = _src.generate()

        return GeneratorOf<[P]> {
            return g.next()
        }
    }

}

class Child<C>: Parent<C> {
    var _ary:[C] = []
}

extension Child: SequenceType {

    typealias Generator = GeneratorOf<C> // <-- HERE

    func generate() -> GeneratorOf<C> {

        var g = _ary.generate()

        return GeneratorOf<C> {
            return g.next()
        }
    }
}