2

でいくつかのブログを見たことがPimp my Library patternありますが、これらはクラスに動作を追加するのにうまく機能しているようです。

しかし、私が持っていて、case classそれをしたい場合はどうadd data membersなりますか? ケース クラスとして拡張することはできません (ケース クラスからの継承は非推奨/強くお勧めしません)。これらの pimp パターンのいずれかで、ケース クラスにデータを追加できますか?

4

2 に答える 2

7

いいえ -強化されたインスタンスは通常破棄されるため、これを機能させる方法がわかりません(注: 新しい pimp-my-library パターンは、enrich-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

ただし、これは実際には役に立たないと思います。ラッパーがあります。これを明示したほうがいい

于 2012-06-15T15:12:49.733 に答える
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]

于 2012-06-15T17:15:13.283 に答える