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的初学者。
答案 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
是包含不可变数据结构的val
。 a
是指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
。