val或var在不可变对象中的重要性

时间:2015-09-27 06:30:50

标签: scala

val或var 是否会在列表或元组之类的不可变对象中产生差异?

scala> val ab = List(1,2,3)
ab: List[Int] = List(1, 2, 3)

scala> var ab = List(1,2,3)
ab: List[Int] = List(1, 2, 3)

我是scala的初学者。

3 个答案:

答案 0 :(得分:4)

你可能会混淆不变性的两个不同方面。局部变量ab引用内存中的某个对象,在本例中为List。当您将ab声明为val时,您正在指示编译器ab将始终引用同一对象。由于List是不可变的,因此其内容永远不会更改,但引用它的var可能会重新分配给其他List

scala> import scala.collection.mutable.MutableList
import scala.collection.mutable.MutableList

scala> val a = List(1,2,3,4)
a: List[Int] = List(1, 2, 3, 4)

scala> val b = MutableList(1,2,3,4)
b: scala.collection.mutable.MutableList[Int] = MutableList(1, 2, 3, 4)

scala> var c = List(1,2,3,4)
c: List[Int] = List(1, 2, 3, 4)

此处,a是包含不可变数据结构的vala是指List(1,2,3,4),并且始终会这样做。

val b指的是MutableList。我们可以更改MutableList的内部内容,但我们无法将b分配给其他MutableList

scala> b += 5
res6: b.type = MutableList(1, 2, 3, 4, 5)

scala> b = MutableList(2,3,5,7)
<console>:12: error: reassignment to val
       b = MutableList(2,3,5,7)
         ^

对于var c,我们有一个引用不可变数据结构List的变量,但可以将其重新分配给不同的List

scala> c = c :+ 5
c: List[Int] = List(1, 2, 3, 4, 5)

请注意,:+运算符(与上面的+=运算符不同)不会更改List引用的c。相反,它会创建List的副本,并附加元素5。由于c被声明为var,我们可以将此列表分配给c

答案 1 :(得分:3)

ab指向的对象是否可变是不切实际的。 val表示您将来不能将ab分配给其他值,而var允许它。

尝试在每种情况下重复分配,看看会发生什么:

scala> val ab = List(1,2,3)
ab: List[Int] = List(1, 2, 3)
scala> ab = List(1,2,3)
reassignment to val; not found: value ab

scala> var ab = List(1,2,3)
ab: List[Int] = List(1, 2, 3)
scala> ab = List(1,2,3)
ab: List[Int] = List(1, 2, 3)

答案 2 :(得分:-2)

这是一种风格问题。

在Scala中使用val通常优先使用var,因为(功能)编程不变性使得更容易推理程序。

因此,如果你能够得到你想要的东西而不诉诸于var,那就是你要走的路。

var的典型应用是,如果您想使用不可变数据结构并更新它对结构共享的好处。

var data = List.empty[String] // var is importan here
def addToData(s: String) : Unit = { data = s :: data } 

使用可变数据结构可以实现同样的目标

import scala.collection.mutable.ArrayBuffer

val data = ArrayBuffer.empty[String]
data += "Hello" // this function is here from the beginning

如需深入讨论,请查看value