我很难理解为什么Swift中有两种不同的结构几乎相同。
编辑:我想我还是不明白什么"懒惰"按顺序意味着...... F.e。使用这个使用SequenceOf的代码,该代码据说不是懒惰的:
func myMap<S: SequenceType, V>(source: S,
selector: S.Generator.Element -> V) -> SequenceOf<V> {
let seq = SequenceOf {
_ -> GeneratorOf<V> in
var gen = source.generate()
return GeneratorOf {
let v = gen.next()
println(v)
return v == nil ? nil : selector(v!)
}
}
return seq
}
让我们用
来调用它 let a = myMap([1, 2, 3], { $0 * 2 })
var gen = a.generate()
let v1 = gen.next()
let v2 = gen.next()
打印
可选(1)
可选(2)
看起来很懒...
编辑#2:
当在懒惰序列上使用地图时,无论如何似乎都在急切地评估元素:
struct TransientView<S: SequenceType> : SequenceType {
private let seq: S
init(_ seq: S) {
self.seq = seq
}
func generate()
-> GeneratorOf<S.Generator.Element> {
var g = seq.generate()
return GeneratorOf {
println("next")
return g.next()
}
}
}
let seq = lazy(map(TransientView([1, 2, 3]), { $0 * 2 }))
打印&#34; next&#34; 4次......
编辑#3。以下是我目前对此的看法:说#34; SequenceOf不是懒惰&#34;是错误的。更确切地说,#4; SequenceOf使用非惰性.map,.filter等进行扩展&#34;。完全可以编写适用于任何序列的map,filer等惰性版本,包括SequenceOf。但是,Apple决定采用“懒惰”#34;范例不仅适用于序列的实例,也适用于序列元素 - 因此,如果将序列变量声明为惰性,则使用LazySequence,因此扩展是惰性的。我认为这是错误的方法,懒惰的声明不应该转移到元素 - 相反,元素应该保持懒惰,只要它是可能的。很容易将懒惰转换为渴望,但不可能。
答案 0 :(得分:12)
SequenceOf不是懒惰的吗?
正确。这不是懒惰。这就是懒惰形式存在的原因。
每种用途的用途是什么?
Airpseed Velocity可能对各种类型进行了最全面的讨论。 SequenceOf
提供了从闭包生成序列的简单方法。它还提供了一种&#34;序列类型转换&#34;将一种序列类型转换为另一种序列类型。
LazySequence
主要使用lazy
函数创建。 Airspeed Velocity&#39; s Working at being lazy给出了很好的介绍。它的目的是避免在实际需要之前生成元素,这对于无限序列特别有用,但在任何可能不需要所有元素的情况下都很有用,并且它们非常容易生成。
我是否提到你应该阅读Airspeed Velocity如果你想深入了解这些东西?但是仍然值得记住的是,我们只能从标题中推断出我们可以从devforum讨论中获得的内容,以及从我们对Swift知道的内容中得到的内容。较低级别的类型尚未有详细记录,并且不属于任何官方的#34; docs,他们已经多次改变了beta。因此,在未来的版本中,正是 Swift团队对他们的意图并不总是很容易。这是迄今为止我们所知道的最好的。
编辑:正如我在评论中指出的那样,没有map
函数在6.1b3中获取并返回LazySequence
。 map
上只有LazySequence
方法。但是如果我们想要的话,我们可以建立一个,也许他们最终会添加它:
func map<S: SequenceType, U>(source: LazySequence<S>, transform: S.Generator.Element -> U) -> LazySequence<MapSequenceView<S, U>> {
return source.map(transform)
}