【问题标题】:Question about Scala variable Mutability关于Scala变量可变性的问题
【发布时间】:2010-07-27 09:00:09
【问题描述】:

我了解 val 关键字确定基础变量是不可变类型(以后无法重新分配)。现在我在 scala 编程中遇到了一段(第 3 章,scala 的下一步 - 使用类型参数化数组),它指出

val greetStrings: Array[String] = new Array[String](3)
greetStrings(0) = "Hello"
greetStrings(1) = ", "
greetStrings(2) = "world!\n"

这三行代码说明了 一个需要理解的重要概念 关于 Scala 的含义 瓦尔。当你定义一个变量时 val,变量不能被重新赋值, 但它所指的对象 可能仍然会改变。所以 在这种情况下,您无法重新分配 GreetStrings 到不同的数组; greetStrings 将始终指向 与它相同的 Array[String] 实例 它被初始化了。但你可以改变 该 Array[String] 的元素 随着时间的推移,所以数组本身是 可变的。

所以改变数组元素是有效的。如果我们这样定义它是无效的

greetStrings = Array("a","b","c")

满足以下条件

当你定义一个变量时 val,变量不能被重新赋值, 但它所指的对象 可能仍会更改。

但是如果我声明这样的事情

val str = "immutable string"

根据书中给出的定义

这是什么意思在上面的代码行中它所引用的对象仍然可能被更改??

【问题讨论】:

    标签: scala immutability


    【解决方案1】:

    声明 val 并不保证甚至暗示不可变类型。它只声明你可能在 Java 中调用的 final 变量。无法重新分配标识符,但值可能是可变类型。

    在您的字符串值示例中,您同时具有 val 和不可变类型 String。所以这个标识符既不可重新分配也不可修改(不可变)。

    【讨论】:

    • 感谢 Elmo.. 所以“它所引用的对象可能仍可能被更改”仅适用于使用 val(immutable)...声明的数组。??
    • 嗨拉梅什。在 Scala 中,Array 是可变的(但您不能更改它的长度)。如果你想要一个不可变的集合实现,你可以试试 List。
    • List 存在可变和不可变版本。可变版本称为 ListBuffer。对比java中的String和StringBuffer/StringBuilder,String是不可变的,StringBuffer/StringBuilder是可变的。见*.com/questions/1241166/…
    • 请注意,List 与不可变的Array是同一类东西。 List 的行为类似于链表 - 您没有像数组中那样的有效随机访问。如果您需要不可变数组,请使用scala.collections.immutable.IndexedSeq