【问题标题】:What's lazy about views on Scala's mutable collections?Scala 可变集合的视图有什么懒惰之处?
【发布时间】:2019-10-12 11:40:35
【问题描述】:

我认为这个问题本质上是关于可变性背景下的惰性是什么。

Scala 编程(或the docs)中,他们给出了如何在不可变和可变集合上使用视图的示例。在该部分中,他们声明

[transformer 方法] 将至少一个集合作为其接收对象,并在其结果中生成另一个集合。 ... view 是一种特殊的集合,它代表一些基本集合,但会延迟实现其所有转换器。

他们给出了不可变集合的例子,我理解懒惰是如何工作的。但是我正在努力解决惰性在可变集合示例中所扮演的角色:

[对可变序列的视图] 上的许多转换器函数提供了进入原始序列的窗口...一个示例...

val arr = (0 to 9).toArray
val subarr = arr.view.slice(3, 6)

视图不会复制这些元素,它只是提供对它们的引用。

def negate(xs: collection.mutable.Seq[Int]) = 
  for (i <- 0 until xs.length) xs(i) = - xs(i)

negate(subarr)
arr  // Array(0, 1, 2, -3, -4, -5, 6, 7, 8, 9)

我明白为什么我们会得到这个答案。但是变压器slice有什么懒惰的呢?我已经将惰性理解为仅在需要时才计算值(例如不可变集合示例)。但是slice 中的值永远不会被计算,它们只是对arr 中的值的引用,即使在调用negate 之后也是如此。这是我对懒惰的误解吗?还是文档以另一种方式使用懒惰?还是别的什么?

【问题讨论】:

  • 不可变集合发生的每一个懒惰的事情也会发生在可变集合中。

标签: scala collections lazy-evaluation lazy-sequences


【解决方案1】:

这是这种懒惰行为的一个更好的例子:

val a = Array(1,2,3)
val b = a.map(_ + 5)
val c = a.view.map(_ + 5)
println(b(1)) //prints 7
println(c(1)) // prints 7

a(1) = 5

println(b(1)) // still prints 7, since that array was computed on instantiation
println(c(1)) // now prints 10, since elements of c are lazily evaluated each time.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-24
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-20
    • 2021-08-12
    • 2012-11-04
    相关资源
    最近更新 更多