List.view 和 LazyList 有什么区别?
What is the difference between List.view and LazyList?
我是 Scala 的新手,我刚刚了解到创建 LazyList
是为了替换 Stream
,同时他们将 .view
方法添加到所有集合中。
所以,我想知道为什么 LazyList
添加到 Scala 集合库中,我们什么时候可以做 List.view
?
我刚刚看了 Scaladoc,似乎唯一的区别是 LazyList
有记忆,而 View
没有。我是对还是错?
Stream
元素是惰性实现的 除了 第一个(头)元素。这被视为一种缺陷。
一个 List
视图被懒惰地重新评估,但据我所知,必须首先完全实现。
def bang :Int = {print("BANG! ");1}
LazyList.fill(4)(bang) //res0: LazyList[Int] = LazyList(<not computed>)
Stream.fill(3)(bang) //BANG! res1: Stream[Int] = Stream(1, <not computed>)
List.fill(2)(bang).view //BANG! BANG! res2: SeqView[Int] = SeqView(<not computed>)
在 2.13 中,您不能强制从视图返回到原始集合类型:
scala> case class C(n: Int) { def bump = new C(n+1).tap(i => println(s"bump to $i")) }
defined class C
scala> List(C(42)).map(_.bump)
bump to C(43)
res0: List[C] = List(C(43))
scala> List(C(42)).view.map(_.bump)
res1: scala.collection.SeqView[C] = SeqView(<not computed>)
scala> .force
^
warning: method force in trait View is deprecated (since 2.13.0): Views no longer know about their underlying collection type; .force always returns an IndexedSeq
bump to C(43)
res2: scala.collection.IndexedSeq[C] = Vector(C(43))
scala> LazyList(C(42)).map(_.bump)
res3: scala.collection.immutable.LazyList[C] = LazyList(<not computed>)
scala> .force
bump to C(43)
res4: res3.type = LazyList(C(43))
如果调用者需要选择结果类型,则采用视图并可选择返回严格实现的函数也必须采用 "forcing function",例如 _.toList
。
我在日常工作中不会做这种事情,但这种行为让我感到惊讶。
我是 Scala 的新手,我刚刚了解到创建 LazyList
是为了替换 Stream
,同时他们将 .view
方法添加到所有集合中。
所以,我想知道为什么 LazyList
添加到 Scala 集合库中,我们什么时候可以做 List.view
?
我刚刚看了 Scaladoc,似乎唯一的区别是 LazyList
有记忆,而 View
没有。我是对还是错?
Stream
元素是惰性实现的 除了 第一个(头)元素。这被视为一种缺陷。
一个 List
视图被懒惰地重新评估,但据我所知,必须首先完全实现。
def bang :Int = {print("BANG! ");1}
LazyList.fill(4)(bang) //res0: LazyList[Int] = LazyList(<not computed>)
Stream.fill(3)(bang) //BANG! res1: Stream[Int] = Stream(1, <not computed>)
List.fill(2)(bang).view //BANG! BANG! res2: SeqView[Int] = SeqView(<not computed>)
在 2.13 中,您不能强制从视图返回到原始集合类型:
scala> case class C(n: Int) { def bump = new C(n+1).tap(i => println(s"bump to $i")) }
defined class C
scala> List(C(42)).map(_.bump)
bump to C(43)
res0: List[C] = List(C(43))
scala> List(C(42)).view.map(_.bump)
res1: scala.collection.SeqView[C] = SeqView(<not computed>)
scala> .force
^
warning: method force in trait View is deprecated (since 2.13.0): Views no longer know about their underlying collection type; .force always returns an IndexedSeq
bump to C(43)
res2: scala.collection.IndexedSeq[C] = Vector(C(43))
scala> LazyList(C(42)).map(_.bump)
res3: scala.collection.immutable.LazyList[C] = LazyList(<not computed>)
scala> .force
bump to C(43)
res4: res3.type = LazyList(C(43))
如果调用者需要选择结果类型,则采用视图并可选择返回严格实现的函数也必须采用 "forcing function",例如 _.toList
。
我在日常工作中不会做这种事情,但这种行为让我感到惊讶。