在Scala 2.8集合框架中,
view
和toStream
有什么区别?在视图中,每次访问元素时都会重新计算。在流中,元素在被评估后保留不变。
例如:
val doubled = List(1,2,3,4,5,6,7,8,9,10).view.map(_*2)
println(doubled.mkString(" "))
println(doubled.mkString(" "))
将对每个元素重新评估两次映射。一次用于第一个println,另一次用于第二个println。相比之下,
val doubled = List(1,2,3,4,5,6,7,8,9,10).toStream.map(_*2)
println(doubled.mkString(" "))
println(doubled.mkString(" "))
只会将元素加倍一次。
视图就像是创建集合的配方。每当您请求视图的元素时,它都会执行该配方。
流就像是拿着一堆干擦卡片的人。这个人知道如何计算集合的后续元素。您可以向他请求集合的下一个元素,并给您一张写有该元素的卡片和一根系在他手指上的绳子(以帮助他记住)。此外,在他给你一张新卡片之前,他会解开第一根绳子并将其系到新卡片上。
如果您保留第一张卡片(即保留对流的头部的引用),当您请求下一个元素时,您可能最终会用完卡片(即内存),但是如果您不需要返回到第一个元素,则可以切断绳子并将不需要的卡片交还给这个人,然后他可以重复使用它们(它们是干擦卡片)。这就是流如何表示无限序列而不会耗尽内存的方式。