斯卡拉:如何避免变异?

时间:2012-01-29 15:11:16

标签: scala mutation

当需要积累一些数据时,这是很常见的。我习惯这样做的方法是将数据块附加到数组。但这对scala来说是一种不好的做法,所以我该如何避免它呢?

3 个答案:

答案 0 :(得分:4)

嗯,有两种处理累积的通用方法:递归和折叠。让我们看看每个的非常简单的例子,来计算列表值的总和。

def sumRecursively(list: List[Int]): Int = {
  def recurse(list: List[Int], acc: Int): Int =
    if (list.isEmpty) acc
    else recurse(list.tail, acc + list.head)
  recurse(list, 0)
}

def sumFolding(list: List[Int]): Int =
  list.foldLeft(0){ case (acc, n) => acc + n }

这方面有很多变化,可以更好地处理这种情况。

答案 1 :(得分:2)

实际上,事实并非如此。您可以在scala中使用Vector,默认情况下,它是scala.collection.immutable包的一部分。这将创建一个不可变集合,每次附加它时都会返回一个新的(不同的)实例。

更多信息:

http://www.scala-lang.org/docu/files/collections-api/collections_15.html

答案 2 :(得分:2)

对于大多数常见用途,“map”和“flatMap”操作用于在功能上生成数据结构。两者都以一个数据结构开始,对其中的每个元素应用一些操作,并返回与原始元素形状相同的新数据结构。它们在如何填充新数据结构方面有所不同。这两个是如此常见和如此强大,以至于Scala包含一个特殊的语法,即for-comprehension,以支持它们。 for-comprehension看起来表面上类似于Java风格的for循环,但实际上编译为一系列map和flatMap调用(在其他一些调用中)。

在函数式编程中,通常会将问题从一个数据结构分解为另一个数据结构,而不是明确地描述构建和销毁数据结构所需的步骤。这需要一些人习惯,特别是在弄清楚要启动什么数据结构时。一旦掌握了它,这是一项非常强大的技术,可以清晰,准确地表达大块功能,并且几乎没有空间容纳蠕虫。

值得注意的是,“map”和“flatMap”实际上是另一个更强大的功能的特殊情况:“fold”。 “fold”(由于技术原因同时实现为“foldLeft”和“foldRight”)可用于构建数据结构并将其分解。