我在Pimp my Library pattern
上看过一些博客,这些博客似乎很适合在课堂上添加行为。
但是如果我有一个case class
而我想add data members
呢?作为案例类,我无法扩展它(从案例类继承被弃用/强烈不鼓励)。这些pimp模式是否允许我将数据添加到案例类?
答案 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]
一起使用。