我注意到方法combinations
(从这里)返回Iterator
。这个方法应该是"懒惰的",这看起来是合理的。避免提前生成所有的组合。现在我想知道,为什么它返回Iterator
而不是Stream
(这是Scala中的惰性列表)。
combinations
返回Iterator
而不是Stream
呢?
对于Stream
,更有可能所有生成的值都将保存在内存中。
scala> val s = Stream.iterate(0)(_ + 1)
s: scala.collection.immutable.Stream[Int] = Stream(0, ?)
scala> s.drop(3).head
res1: Int = 3
scala> s
res2: scala.collection.immutable.Stream[Int] = Stream(0, 1, 2, 3, ?)
当您保留对Stream
的引用时,所有生成的元素将保留在内存中。使用Iterator
,这种情况不太可能发生。
当然,这并不一定是Scala库被设计成这样的原因…
我认为是因为Stream缓存了所有先前返回的元素,所以您最终会在内存中使用它们。迭代器只返回下一个
正如我在CombinationsItr
代码中看到的,每次调用next
方法时都有一个延迟计算。看到https://lampsvn.epfl.ch/trac/scala/browser/scala/tags/R_2_9_1_final/src//library/scala/collection/SeqLike.scala L198
所以当使用next
获得下一个组合时,例如:
scala> val combinations = "azertyuiop".combinations(2)
scala> combinations.next
res9: String = az
next
的结果被惰性求值
Iterator
比Stream
便宜。如果需要,可以从前者得到后者。