gpt4 book ai didi

swift - 使用包装器时奇怪的 SequenceType 行为

转载 作者:搜寻专家 更新时间:2023-10-31 22:46:03 25 4
gpt4 key购买 nike

我有一个包装序列的包装器:

struct SequenceWrapper<T>: SequenceType {
var sequence: AnySequence<T>

func generate() -> AnyGenerator<T> {
return sequence.generate()
}
}

let wrapper = SequenceWrapper(sequence: AnySequence(1 ... 10))

如果我创建两个生成器并在两者上都调用 next(),不会发生任何奇怪的事情:

let generator = wrapper.generate()
let another = wrapper.generate()

generator.next() // 1
another.next() // 1

到目前为止,还不错。但是,如果我首先在我的包装器上调用 dropFirst(),我会得到奇怪的行为:

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?

如果我使用 dropLast() 而不是 dropFirst(),则输出为 11,正如预期的那样。

如果我不使用我制作的包装器 struct,而是直接使用 AnySequence 实例,则不会发生任何异常情况:

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

我无法理解这一点。这是怎么回事?

最佳答案

您必须通过行为进行调试才能了解具体行为,但这很可能发生,因为 SequenceTypenot required to be iterable multiple times .

SequenceType makes no requirement on conforming types regarding whether they will be destructively "consumed" by iteration. To ensure non-destructive iteration, constrain your sequence to CollectionType.

As a consequence, it is not possible to run multiple for loops on a sequence to "resume" iteration:

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 makes no requirement about the behavior in that case. It is not correct to assume that a sequence will either be "consumable" and will resume iteration, or that a sequence is a collection and will restart iteration from the first element. A conforming sequence that is not a collection is allowed to produce an arbitrary sequence of elements from the second generator.

换句话说,您通过调用 generate() 两次获得的两个生成器不能保证不会相互干扰。事实上,一个类型同时实现 SequenceTypeGeneratorType 并将 generate() 实现为 return self 是合法的.任何共享状态(来自成员引用,或者如果序列本身是引用类型)将在生成器之间共享,这就是为什么你应该只创建一个。

关于swift - 使用包装器时奇怪的 SequenceType 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37890761/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com