Scala中的val赋值

时间:2018-01-02 07:03:40

标签: scala

在Scala中,val是无法修改的变量,即不允许重新分配。但是在下面的代码中,我可以重新分配val,尽管它被重新分配给同一个对象(它是可变的地图):

val treasureMap = Map[Int, String]()
treasureMap += (1 -> "Go to island.")
treasureMap += (2 -> "Find big X on ground.")
treasureMap += (3 -> "Dig.")

因此,它给人的印象是val可以重新分配给同一个对象而不是另一个对象。

此外,

val str1 = "Hi"
val str2 = "Hi"
println(str1.eq(str2))

此代码的输出为true,表示只有一个字符串文字实例。

通过所有这些行为,当我尝试将str1重新分配给同一个对象时,为什么下面的代码会出现编译错误:

str1 = "Hi"

在这里,我将str1分配回它最初引用的同一个对象。

2 个答案:

答案 0 :(得分:2)

当您指定一个Map(或一般的集合)时,您正在为该集合的入口点指定一个标签(简单地说就是这样)。

所以当你写

treasureMap += (1 -> "Go to island.")

您没有为treasuremap分配任何新内容,只是在同一个地图中添加了一个元素,而“标签指的是相同的入口点。

关于

val str1 = "Hi"
val str2 = "Hi"

它们是包装java字符串的两个字符串值,因此是意外行为。您可以查看此答案== and eq Operators以获得澄清

答案 1 :(得分:0)

val背后的想法是保护重新分配价值。

例如,

scala> val data = 100
data: Int = 100

scala> data = 200
<console>:13: error: reassignment to val
       data = 200
            ^

由于scala也有可变集合,例如您在示例中使用的mutable.Map,它允许您改变数据而不是重新分配。

scala> val treasureMap = scala.collection.mutable.Map[Int, String]()
treasureMap: scala.collection.mutable.Map[Int,String] = Map()

scala> treasureMap += (1 -> "Go to island.")
res65: treasureMap.type = Map(1 -> Go to island.)

现在尝试重新分配,因为你的变量是val

,所以不会让你这样做
scala> treasureMap = scala.collection.mutable.Map[Int, String]()
<console>:13: error: reassignment to val
       treasureMap = scala.collection.mutable.Map[Int, String]()
                   ^

与任何数据结构相同。

scala> val str1 = "some string"
str1: String = some string

scala> str1 = "some another string"
<console>:13: error: reassignment to val
       str1 = "some another string"
            ^