为什么Scala复制无法保留原始类实例的状态?

时间:2018-09-20 17:05:38

标签: scala

似乎copy不会保留原始实例的任何状态,而只是使用基类定义使用新值创建新实例。有人知道为什么要用这种方式实现吗?

scala> case class A(){ var y = 2 }
defined class A

scala> val a = new A()
a: A = A()

scala> a.y = 9
a.y: Int = 9

scala> a.y
res9: Int = 9

scala> val b = a.copy()
b: A = A()

scala> b.y
res10: Int = 2

3 个答案:

答案 0 :(得分:4)

  

有人知道为什么要采用这种方式吗?

此Scala-lang dialog提供了很好的洞察力,说明了为什么采用这种方式。特别是Daniel Sobral的例子很有道理:

  

假设变量应包含一个唯一的数字,这样   实例具有相同的编号?或假设它指向可变的   对象-应该在实例之间共享还是复制   每个实例都有自己的实例。

答案 1 :(得分:3)

这不是错误,也不是可变性问题。

case类的工作方式是其所有功能(等于,哈希码,toString,副本等)都依赖于其构造函数参数(其中某些功能不适用于currying)。

尽管您的变量将是一个val,但您将遇到同样的问题。例如,

case class AAA() {
  val field = 1
}

val instanceA = new AAA() {
  override val field: Int = 5
}

println(instanceA.field)
// 5

println(instanceA.copy().field)
// 1

您的案例分类应该是

case class A(y:Int = 2)

答案 2 :(得分:1)

这不是您问题的直接答案,但这是您如何以惯用的Scala方式完成所需的事情。

final case class A(a: Int = 2) // if a is not provided it will fallback to the default value of 2
val a = A(a = 3) // A(3)
val b = a.copy(a = 9) // A(9) - BTW, this is the same as A(a = 9)

case classes用于为不可变数据对象建模,当您要创建一个与另一个对象共享相同状态的新对象时,copy方法是提供的快捷方式。您要更改的数据。