在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分配回它最初引用的同一个对象。
答案 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"
^