我在Scala中使用了以下示例来说明我的困惑:
import java.util.HashMap
val jhm = new HashMap[String, Int]
jhm.put("myId", 1)
jhm.put("yourId", 2)它允许添加到"jhm“中
现在,如果我在Scala中这样做:
val nmap = Map()
nmap += ("myId" -> 1)它不允许这是预期的。我的问题是:为什么它允许在第一种情况下更改不可变的"val“?
发布于 2017-05-24 14:58:46
val创建了一个不可变的引用,这意味着这个val将始终指向同一个对象。它不能保证对象本身不会改变它自己的状态。
发布于 2017-05-24 15:00:51
HashMap上的put()会改变映射,并且不会返回新的引用。在第二种情况下,您将向不可变映射添加一个值,因此将返回一个新映射。您的Java示例的Scala等效项是:
import collection.mutable.Map
val nmap = Map()[String, Int]
nmap += ("a" -> 1)发布于 2017-05-24 15:53:15
你正在混合两种不同的不变性“用法”。
你可以有一个可变的(var)或者不变的(val)引用,并且这个东西本身可以是可变的或者是不可变的。
例如:
var x = 3
x = 4 // it works, `x` can be reassigned
val y = 3
y = 4 // it fails, `y` can't be reassigned问题是,当“某物”、“引用”具有内部状态时。像Int或String这样的基本类型没有这个问题,但是任何类都可能有这个问题。scala集合对于新的scala程序员来说是一个普遍的痛苦,因为有mutable collections和immutable collections。
不同之处在于,对不可变集合的任何操作都会返回一个新集合,但原始集合保持不变,而在可变集合中,集合本身会被修改。
在您的例子中,您正在使用的scala映射是一个不可变的Map,并且它不包含这样的方法。你可以执行myMap ++ (key -> value)并获得一个新的地图。
当您将引用中的可变性与对象中的可变性/状态混合在一起时,会出现更大的混淆。你应该自己玩一下类似这样的东西:
val x1 = scala.collection.mutable.ListBuffer(1,2,3) // immutable reference to mutable object
// please, never use this in real code
var x2 = scala.collection.mutable.ListBuffer(1,2,3) // mutable reference to mutable object
// please, try to use this as much as possible
val x3 = scala.collection.immutable.List(1,2,3) // immutable reference to immutable object
var x4 = scala.collection.immutable.List(1,2,3) // mutable reference to immutable object如果您有任何疑问,请让我/我们知道,以便我们能够提供帮助
https://stackoverflow.com/questions/44150967
复制相似问题