首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Scala中使用从Java导入的不可变"val“

在Scala中使用从Java导入的不可变"val“
EN

Stack Overflow用户
提问于 2017-05-24 14:52:13
回答 4查看 98关注 0票数 0

我在Scala中使用了以下示例来说明我的困惑:

代码语言:javascript
复制
import java.util.HashMap
val jhm = new HashMap[String, Int]
jhm.put("myId", 1)
jhm.put("yourId", 2)

它允许添加到"jhm“中

现在,如果我在Scala中这样做:

代码语言:javascript
复制
val nmap = Map()
nmap += ("myId" -> 1)

它不允许这是预期的。我的问题是:为什么它允许在第一种情况下更改不可变的"val“?

EN

回答 4

Stack Overflow用户

发布于 2017-05-24 14:58:46

val创建了一个不可变的引用,这意味着这个val将始终指向同一个对象。它不能保证对象本身不会改变它自己的状态。

票数 4
EN

Stack Overflow用户

发布于 2017-05-24 15:00:51

HashMap上的put()会改变映射,并且不会返回新的引用。在第二种情况下,您将向不可变映射添加一个值,因此将返回一个新映射。您的Java示例的Scala等效项是:

代码语言:javascript
复制
import collection.mutable.Map

val nmap = Map()[String, Int]
nmap += ("a" -> 1)
票数 3
EN

Stack Overflow用户

发布于 2017-05-24 15:53:15

你正在混合两种不同的不变性“用法”。

你可以有一个可变的(var)或者不变的(val)引用,并且这个东西本身可以是可变的或者是不可变的。

例如:

代码语言:javascript
复制
var x = 3
x = 4 // it works, `x` can be reassigned 

val y = 3
y = 4 // it fails, `y` can't be reassigned

问题是,当“某物”、“引用”具有内部状态时。像IntString这样的基本类型没有这个问题,但是任何类都可能有这个问题。scala集合对于新的scala程序员来说是一个普遍的痛苦,因为有mutable collectionsimmutable collections

不同之处在于,对不可变集合的任何操作都会返回一个新集合,但原始集合保持不变,而在可变集合中,集合本身会被修改。

在您的例子中,您正在使用的scala映射是一个不可变的Map,并且它不包含这样的方法。你可以执行myMap ++ (key -> value)并获得一个新的地图。

当您将引用中的可变性与对象中的可变性/状态混合在一起时,会出现更大的混淆。你应该自己玩一下类似这样的东西:

代码语言:javascript
复制
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

如果您有任何疑问,请让我/我们知道,以便我们能够提供帮助

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44150967

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档