我们假设我有一个泛型类 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
}
}
这里有什么问题,我该如何解决?
所以问题似乎是通过应用@ 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
}
)的名称在这种情况下可能会引起混淆,因为它们会返回不同的类型。
这似乎是合适的,但取决于具体情况。但通常应该避免模棱两可。
答案 0 :(得分:2)
看来,你可以。只有<{strong> Generator
中Child
的明确类型才有效。但是,我也认为你不应该这样做......
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()
}
}
}