2012-06-15 14 views
2

Pimp my Library pattern에 대한 블로그를 보았습니다. 클래스에 동작을 추가하는 데는 효과가있는 것 같습니다.스칼라 케이스 클래스에 필드 추가하기?

하지만 case class이 있는데 add data members으로 보내고 싶습니다. 사례 클래스로서 확장 할 수 없습니다 (사례 클래스에서 상속하는 것이 더 이상 사용되지 않거나 강력하게 권장되지 않습니다.). 이러한 포주 패턴 중 하나를 사용하여 사례 클래스에 데이터를 추가 할 수 있습니까?

답변

7

아니요 - 풍부한 인스턴스 인이 일반적으로 버려지기 때문에이 작업을 수행하는 방법을 알 수 없습니다 (참고 : 새로 만든 pimp-my-library 패턴은 enrich-my-library입니다). 예를 들어 :

scala> res17: Y 
res19: Y = [email protected] 

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

scala> res19.f 
res20: Float = 4.0 

는 그러나, 나는 실제로이 유용하지 찾을 :

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 

당신은, 랩 된 인스턴스의 보류를 유지 있는지 확인해야합니다. 당신은 래퍼를 가지고 있습니다; 너는 이것을 더 명백하게하는 것이 낫다.

4

이것은 할 수있는 방법이 아니다. 가능성의 증거. 이런 식으로 당신은 많은 문제를 겪을 수 있습니다.

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를 랩합니다.

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

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

그래서 당신은 case class를 사용하거나 override def equals(that: Any) = this eq that.asInstanceOf[AnyRef]와 함께 사용하지 않아야 인해 case class 년대는이 재미있는 동작을 얻을 equals 방법을 무시한다는

참고.

+0

이와 같은 제안을하지 마십시오. 이것은 매우 추악 할뿐만 아니라 안전하지도 않습니다. – drexin

+0

@drexin 원한다면이 threadsafe (단일 jvm에서)를 만들 수 있습니다. – senia

+0

@drexin 네 말이 맞아. 내 대답을 업데이트했습니다. – senia

관련 문제