向Scala案例类添加字段?

时间:2012-06-15 15:00:10

标签: class scala case

我在Pimp my Library pattern上看过一些博客,这些博客似乎很适合在课堂上添加行为。

但是如果我有一个case class而我想add data members呢?作为案例类,我无法扩展它(从案例类继承被弃用/强烈不鼓励)。这些pimp模式是否允许我将数据添加到案例类?

2 个答案:

答案 0 :(得分:7)

不 - 我不知道你是如何做到这一点的,因为丰富的实例通常被抛弃(注意:新的pimp-my-library模式被称为enrich-my-图书馆)。例如:

scala> case class X(i: Int, s: String)
defined class X

scala> implicit class Y(x: X)  {
   |     var f: Float = 0F
   |   }
defined class Y

scala> X(1, "a")
res17: X = X(1,a)

scala> res17.f = 5F
res17.f: Float = 0.0

scala> res17.f
res18: Float = 0.0

您必须确保保留已包装的实例:

scala> res17: Y
res19: Y = Y@4c2d27de

scala> res19.f = 4
res19.f: Float = 4.0

scala> res19.f
res20: Float = 4.0

但是,我觉得这在实践中没用。你有一个包装;你做这个明确的

会更好

答案 1 :(得分:3)

这不是办法。只是可能性的证明。通过这种方式,您可以获得许多问题。

scala> :paste
// Entering paste mode (ctrl-D to finish)

case class A(i: Int)

class B(a: A){
  var s: String = ""
}

object B{
  val as = scala.collection.mutable.WeakHashMap[A, B]()
}

implicit def a2b(a: A) = B.as.getOrElseUpdate(a, new B(a))

// Exiting paste mode, now interpreting.

defined class A
defined class B
defined module B
a2b: (a: A)B

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

scala> a.s = "test"

scala> a.s
res0: String = test

WeakHashMap:一个哈希映射,引用了弱可达的条目。当不再(强烈)引用密钥时,将从此映射中删除条目。该类包装了java.util.WeakHashMap。

请注意,由于case class覆盖了equals方法,您会遇到这种有趣的行为:

scala> A(2).s = "test2"

scala> A(2).s
res2: String = test2

因此您不应使用case class或将其与override def equals(that: Any) = this eq that.asInstanceOf[AnyRef]一起使用。