【问题标题】:Understanding Scala mutable set val reference理解 Scala mutable set val reference
【发布时间】:2017-08-22 08:10:14
【问题描述】:

在第三版“Scala 编程”一书中,我看到了一个我无法理解的示例。为了理解它,我将它输入到 scala 解释器中:

scala> import scala.collection.mutable
import scala.collection.mutable

scala> val movieSet = mutable.Set("Hitch", "Poltergeist")
movieSet: scala.collection.mutable.Set[String] = Set(Poltergeist, Hitch)

scala> movieSet
res3: scala.collection.mutable.Set[String] = Set(Poltergeist, Hitch)  <<< res3

scala> movieSet += "Shrek"
res4: movieSet.type = Set(Poltergeist, Shrek, Hitch)                  <<< res4

我的理解是在 mutable.Set 上执行 += 时,Set 应该就地变异(即分配给它的变量不应该改变),但是引用从 res3 更改为 res4。 另外,我理解“val movieSet”是为了创建一个无法更改的值。这不应该导致“val movieSet”保留在 res3 引用中,而不是更改为 res4 吗?

【问题讨论】:

    标签: scala


    【解决方案1】:

    res3res4 只是对同一对象的附加引用,当您键入具有非单元返回类型但未分配给变量的表达式时,由 scala shell 生成。当您执行+= 时,该方法会改变集合,并再次返回对同一对象的引用,这就是res3res4 最终包含的内容。

    您可以使用eq 方法检查两个值是否实际上是相同的确切对象(不是两个相等的对象)。即,res3 eq movieSetres4 eq movieSet 都应该为真。

    val 将变量限制为始终引用同一个对象,但不限制该对象以任何方式发生变异。

    【讨论】:

    • 感谢 Joe K 的快速响应。我误解了 Scala shell。
    【解决方案2】:

    mutable.Set#+= 有签名

    trait Set[A] {
      def +=(elem: A): this.type
    }
    

    也就是说,它添加一个元素,然后返回自身,大概是这样您就可以像set += "a" += "b" 这样链接调用。 REPL 为返回生成一个新的val 的事实纯粹是因为它不知道更好。如果你在那之后输入了res3,你就会看到这个突变。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-22
      • 2019-12-18
      • 1970-01-01
      • 1970-01-01
      • 2012-03-12
      • 2011-06-11
      相关资源
      最近更新 更多