设计一个可更新的不可变类

时间:2013-12-12 18:37:37

标签: scala

假设我有一个简单的类定义为:

class M () {
  val map = Map()
}

在这种情况下,地图是不可变的,不改变它,我可以将值添加到地图吗?

class M () {
  val map: Map[Int, Int] = Map()

  def setValue(key: Int, value: Int)
}

这是不可变的吗?

我知道你可以做复制对象的技巧,但这样做的用法如下:

val test: M = new M()
val test1: M = test.setValue(2,3)

有没有办法可以做到:     val测试:M =新M()     test.setValue(1,2)     test.setValue(2,3)

或唯一的方法是将地图更改为可变?

4 个答案:

答案 0 :(得分:1)

1)你可以完全不可变 - 这样setValue将产生M类的新实例:

class M(val map: Map[Int, Int] = Map()) {
  def setValue(key: Int, value: Int) = new M(map + (key -> value))
}

单独使用没有多大意义,但可能有这样的解决方案的原因。

2)如果你严格保持地图定义为val,而不是var - 使用可变地图:

import collection.mutable.{Map => MMap}
class M() {
  val map: MMap[Int, Int] = MMap()
  def setValue(key: Int, value: Int) = map += (key -> value)
}

3)最后,你可以使用var,就像其他人指出的一样。

答案 1 :(得分:0)

你可以这样做:

class M[A, B](val map: Map[A, B]) {

  def this() = this(Map.empty[A,B])

  def setValue(a: A, b: B) = new M[A, B](map + (a -> b))
}

要获得新的M,您可以使用构造函数创建一个M,也可以使用setValue使用更新的Map创建新的M.

示例:

val test = new M[Int, Int]()
println(test.map) //Map()
val test1 = test.setValue(2, 3)
println(test1.map) //Map(2 -> 3)

希望这就是你的意思。

答案 2 :(得分:0)

嗯,这是不可变性的一个重点 - 任何潜在的“可变”操作都会创建一个新对象而不是修改现有对象。所以你可能想要map一个var,而不是val,这样看起来就像那样:

class M () {
  var map: Map[Int, Int] = Map()

  def setValue(key: Int, value: Int): map = map + (a -> b)
}

答案 3 :(得分:0)

您是否只想在创建时填充地图并在之后使其不可变?如果是这样,您可以通过M的构造函数传递值:

class M(values:(Int,Int)*) {
  val map = Map(values:_*)
}

val test = new M((1,2), (2,3)) // or new M(1 -> 2, 2 -> 3)