我有一个包装序列的包装器:
struct SequenceWrapper<T>: SequenceType {
var sequence: AnySequence<T>
func generate() -> AnyGenerator<T> {
return sequence.generate()
}
}
let wrapper = SequenceWrapper(sequence: AnySequence(1 ... 10))
如果我生成两个生成器并同时调用这两个生成器,则不会发生任何奇怪的情况:
let generator = wrapper.generate()
let another = wrapper.generate()
generator.next() // 1
another.next() // 1
到目前为止,一切都很好。但是,如果我第一次在包装上调用
next()
let wrapper = SequenceWrapper(sequence: AnySequence(1 ... 10))
let trimmed = wrapper.dropFirst()
let generator = trimmed.generate()
let another = trimmed.generate()
generator.next() // 2
another.next() // 3, huh?
如果我使用
dropFirst()
而不是dropLast()
,输出结果如预期一样为dropFirst()
和1
。如果我不使用我制作的包装器,而是直接使用一个
1
实例,则不会发生任何异常情况:let sequence = AnySequence(1 ... 10)
let trimmed = sequence.dropFirst()
let generator = trimmed.generate()
let another = trimmed.generate()
generator.next() // 2
another.next() // 2, as expected
我听不懂。这是怎么回事?
最佳答案
为了理解特定的行为,您必须调试整个行为,但这很可能是因为SequenceType
是not required to be iterable multiple times。SequenceType
不要求符合以下类型:
它们是否会被迭代破坏性地“消耗”。确保
非破坏性迭代,将序列约束为CollectionType
。
因此,不可能在序列上运行多个for循环来“恢复”迭代:
for element in sequence {
if ... some condition { break }
}
for element in sequence {
// Not guaranteed to continue from the next element.
// [mine: not guaranteed to restart from the beginning either]
}
SequenceType
对这种情况下的行为没有任何要求。它假设一个序列要么是“可消耗的”,这是不正确的。
将恢复迭代,或者序列是集合,并且将
从第一个元素重新开始迭代。一个一致的序列
不允许集合生成
来自第二个生成器的元素。
换言之,您两次调用
generate()
得到的两个生成器不能保证互相干扰。实际上,一个类型同时实现SequenceType
和GeneratorType
和将generate()
实现为return self
是合法的。任何共享状态(来自成员引用,或者序列本身是引用类型)都将在生成器之间共享,这就是为什么您应该只创建一个共享状态的原因。