Scala:集合转换的副作用

时间:2016-02-03 11:44:25

标签: scala collections lazy-evaluation

我试图通过此链接http://docs.scala-lang.org/overviews/collections/views.html了解scala中的观点。

我不明白集合转换有/不是副作用的意思! ?

谢谢

2 个答案:

答案 0 :(得分:1)

通过产生副作用意味着当您在集合转换中执行关闭某些外部状态的代码时,或者具有影响转换结果的任何其他任何副作用的情况。例如:

val l = List(1, 2, 3, 4).view.map(x => {println(x); x + 1})

当您执行此代码时,它将不会打印任何内容,因为view会延迟map的执行。此外,每次尝试迭代此列表时,都会执行map,导致打印值超出预期值。

  var counter = 0
  val ll = for (i <- List(1, 2, 3, 4).view)
            yield { counter += 1; i + 1}
  println(counter)      // 0
  println(ll.toList)    // this executes .force internally
  println(counter)      // 4

以同样的方式行事,但更令人意想不到。 counter仅在迭代事实之后才会增加,并且假设ll是惰性且延迟的,则迭代可能在代码中发生得更深,导致counter在此之前等于0

答案 1 :(得分:0)

Scala具有不可变集合(scala.collection.immutable中的所有内容)。这些集合类型没有修改它们的操作,只是为了获得修改后的副本。

所以例如这个

Set(1) + 2

会给你一个包含1和2的新Set,而不是修改第一组。对于map,flatMap,filter等转换也是如此。

视图不会改变任何相关内容。视图和它所基于的集合之间的唯一区别是,对视图的(大多数)操作是惰性的,即不计算中间结果。

val l1 = List(1,2) 
val l2 = List(1,2).map(x => x + 1) // a new List(2,3) is computed here
l2.foreach(println) // the elements of l2 are just printed

有了观点:

val v2 = l1.view.map(x => x + 1) // nothing is computed here
v2.foreach(println) // the values are computed step by step