为符合 'SequenceType' 的 class 的子 class 更改 'generate()' 方法
Changing the 'generate()'-method for a subclass of a class conforming to 'SequenceType'
假设我有一个通用classParent<P>
,它符合SequenceType
协议,通过实施 generate()
方法 :
class Parent<P> {
//...
}
extension Parent: SequenceType {
func generate() -> GeneratorOf<[P]> {
//...
return GeneratorOf<[P]> {
//return the next element, or nil to stop
}
}
现在 generate()
方法显然不是 return 类型 P
的元素,而是 [P]
.
现在让我们实现一个子class Child<C>
:
class Child<C>: Parent<C> {
//...
}
Child
也应该符合 SequenceType
,但不应该 return 类型 [C]
的元素,而是 C
.
从逻辑上讲,我会尝试实现自己的 generate()
方法:
extension Child: SequenceType {
func generate() -> GeneratorOf<C> {
//...
return GeneratorOf<C> {
//return the next element, or nil to stop
}
}
虽然这不起作用,并且 swift 抛出错误:
<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]> {
这是什么问题,我该如何解决?
更新 #1:
所以问题似乎可以通过应用@rintaro 的方法来解决,该方法只在 Child
class[ 中为 Generator
定义 typealias
.
但是正如@AirspeedVelocity 和@NateCook 在评论中所讨论的,这不是一个非常可行的方法,因为 Child
class 也可以是 subclassed.
也有人说可以创建一个 实例 属性(computed 我假设)return正在处理所需元素的 序列 :
class Parent<P> {
var asSequence: [[P]] {
//some kind of getter
}
//...
}
class Child<C>: Parent<C> {
override var asSequence: [C] {
//some kind of getter
}
//...
}
实例 仍然可以在 for-in-loops:
中使用
for element in someParent.asSequence {
//element is of type [P]
}
for element in someChild.asSequence {
//element is of type C
}
这会是 "best" 方法吗?
更新#1.1:
正如@MichaelWelch 所建议的,属性 (asSequence
) 的名称在这种情况下可能会造成混淆,因为它们 return 不同的类型。
这似乎是合适的,但要视情况而定。但一般应避免歧义。
看来,你可以。 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()
}
}
}
假设我有一个通用classParent<P>
,它符合SequenceType
协议,通过实施 generate()
方法 :
class Parent<P> {
//...
}
extension Parent: SequenceType {
func generate() -> GeneratorOf<[P]> {
//...
return GeneratorOf<[P]> {
//return the next element, or nil to stop
}
}
现在 generate()
方法显然不是 return 类型 P
的元素,而是 [P]
.
现在让我们实现一个子class Child<C>
:
class Child<C>: Parent<C> {
//...
}
Child
也应该符合 SequenceType
,但不应该 return 类型 [C]
的元素,而是 C
.
从逻辑上讲,我会尝试实现自己的 generate()
方法:
extension Child: SequenceType {
func generate() -> GeneratorOf<C> {
//...
return GeneratorOf<C> {
//return the next element, or nil to stop
}
}
虽然这不起作用,并且 swift 抛出错误:
<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]> {
这是什么问题,我该如何解决?
更新 #1:
所以问题似乎可以通过应用@rintaro 的方法来解决,该方法只在 Child
class[ 中为 Generator
定义 typealias
.
但是正如@AirspeedVelocity 和@NateCook 在评论中所讨论的,这不是一个非常可行的方法,因为 Child
class 也可以是 subclassed.
也有人说可以创建一个 实例 属性(computed 我假设)return正在处理所需元素的 序列 :
class Parent<P> {
var asSequence: [[P]] {
//some kind of getter
}
//...
}
class Child<C>: Parent<C> {
override var asSequence: [C] {
//some kind of getter
}
//...
}
实例 仍然可以在 for-in-loops:
中使用for element in someParent.asSequence {
//element is of type [P]
}
for element in someChild.asSequence {
//element is of type C
}
这会是 "best" 方法吗?
更新#1.1:
正如@MichaelWelch 所建议的,属性 (asSequence
) 的名称在这种情况下可能会造成混淆,因为它们 return 不同的类型。
这似乎是合适的,但要视情况而定。但一般应避免歧义。
看来,你可以。 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()
}
}
}