Class 更改';生成()-符合';SequenceType';

Class 更改';生成()-符合';SequenceType';,class,swift,subclass,generator,sequence,Class,Swift,Subclass,Generator,Sequence,假设我有一个泛型类Parent,它通过实现generate()方法符合SequenceType协议: extension Child: SequenceType { func generate() -> GeneratorOf<C> { //... return GeneratorOf<C> { //return the next element, or nil to stop } } Child也应该符合Sequ

假设我有一个泛型类
Parent
,它通过实现
generate()
方法符合
SequenceType
协议:

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

    return GeneratorOf<C> {
        //return the next element, or nil to stop
    }
}
Child
也应该符合
SequenceType
,但不应该返回
[C]
类型的元素,而是
C

从逻辑上讲,我会尝试实现自己的
generate()
方法:

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

    return GeneratorOf<C> {
        //return the next element, or nil to stop
    }
}
这些实例仍然可以在for循环中使用:

这是“最佳”方法吗

更新#1.1:

正如@MichaelWelch所建议的,在这种情况下属性(
asSequence
)的名称可能会令人混淆,因为它们返回不同的类型。

这似乎是适当的,但要视情况而定。但通常应该避免歧义。

看来,你可以。
生成器的显式typealias仅在子项中起作用。但是,我也认为你不应该这样做

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()
        }
    }
}
类父级

{ var[u src:[[P]]=[] } 扩展父项:SequenceType{ func generate()->GeneratorOf{ var g=_src.generate() 返回发生器{ 返回g.next() } } } 类子:父{ 变量:[C]=[] } 扩展子项:SequenceType{ typealias生成器=GeneratorOf//GeneratorOf{ var g=_ary.generate() 返回发生器{ 返回g.next() } } }


您可以考虑让父类拥有一个返回序列的方法(而不是实现序列集本身)。然后,子对象将继承该方法,并可以添加另一个具有新名称的方法,该方法将返回不同的SequenceOf。(由于返回的元素不同,这些方法的调用者无论如何都需要知道它们之间的差异)在我看来,根本错误在于有两个具有不同结果类型的
generate
方法会使Swift为
Generator
推断出两个不同类型的别名,属于
SequenceType
的别名。您不能用其他类型重写类型别名,因此会根据该冲突产生错误@MichaelWelch的想法很好——不要让它们直接符合
SequenceType
,而是使用一个方法或计算属性,以序列的形式访问内容。@nate-我相信您可以覆盖类型别名:
类a{typealias t=Int};类B:A{typealias T=String;func f()->A.T{return 1};println(B().f())
可以正常工作(对于fine的某些定义:)。然而,我找不到一个语法来指代B的t(
B.t
是不明确的-大概是因为
a.t
也是
B.t
)。如果有这样的语法,也许你可以编译问题的代码。然而,我和你们一样,这可能不是你们应该做的……啊,所以问题在于重写方法中的模糊性:
extension A{func g()->T{return 1};扩展名B{override func g()->T{return“a”}
->
'T'对于此上下文中的类型查找不明确。如果是这样,重写类型别名是否应该是编译器错误?它基本上毒害了子类中的类型别名。还导致了关于如何实现两个协议的问题(即使是使用结构),这两个协议都需要相同名称的类型别名,但需要将其别名为不同的类型。哈,不错。你和孙子孙女的关系可能不太好:)我不想维护任何使用这种技巧的类的代码。:-)为什么我有时要取回一系列的孩子,有时还要取回一系列的父母??
<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]> {
class Parent<P> {
    var asSequence: [[P]] {
        //some kind of getter
    }

    //...
}

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

    //...
}
for element in someParent.asSequence {
    //element is of type [P]
}

for element in someChild.asSequence {
    //element is of type C
}
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()
        }
    }
}