我在 上看到了一些博客Pimp my Library pattern
,这些似乎可以很好地为类添加行为。
但是,如果我有一个case class
并且我想要add data members
它怎么办?作为一个案例类,我不能扩展它(不推荐/强烈反对从案例类继承)。这些皮条客模式中的任何一个都允许我将数据添加到案例类吗?
不 - 我看不出你怎么能做到这一点,因为丰富的实例通常被丢弃(注意:新的 pimp-my-library 模式被称为丰富我的图书馆)。例如:
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
但是,我发现这在实践中没有用。你有一个包装器;你最好把这个明确
这不是办法。只是可能性的证明。通过这种方式,您可能会遇到很多问题。
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
's 被覆盖的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]
。