2012-06-28 4 views
7

다중 매개 변수 케이스 클래스와 일치하는 추출기를 작성하려고합니다. 단순화 된 예 :스칼라 - 추출기가 혼란을 풀다

case class X(p1: String, p2: Int) 

각 추출기 개체에 대해 고정 값을 정의하고 싶습니다. p2는 사용시 정의됩니다. 패턴 매칭

object A { 
    def apply(p2: Int): X = X("A", p2) 
} 

object B { 
    def apply(p2: Int): X = X("B", p2) 
} 

... 

I은 ​​: 방법을 적용하여 예 (A는 B, 등등이 경우 클래스와 서브 클래스 X가 될 수없고, 또한이 경우로서 X (,)를 사용하고자) 다음과 같이 일치하도록 싶습니다

X("A", 2) match { 
    case A(2) => true // <- should match: p1="A" and p2=2 
    case A(_) => true // <- should match: p1="A" and p2=_ 
    case X("A", _) => true // <- should match: p1="A" and p2=_ 
    case A(1) => false // <- should not match 
    case B(2) => false // <- should not match: p1="B" and p2=2 
} 

을 나는 등 A, Bunapply 방법을 정의 할 필요가 알지만, 서명 및 로직이 있어야 할 것을 철저 혼란 스러워요 :

object A { 
    def unapply(x: ???): Option[???] = { 
    ??? 
    } 
} 

도와주세요.

답변

14

unapply은 Any를 취하여 추출 할 내용이 모두 Option입니다. 귀하의 경우에는이 될 것이다 :

솔직히 말해서, 당신이 해낸 예 AB없이 다시 작성할 수 있지만,
scala> case class X(p1: String, p2: Int) 
defined class X 

scala> object A { 
    | def unapply(target: Any): Option[Int] = 
    |  PartialFunction.condOpt(target) { 
    |  case X("A", p2) => p2 
    |  } 
    | } 
defined module A 

scala> val A(x) = X("A", 1) 
x: Int = 1 

scala> val A(x) = X("B", 1) 
scala.MatchError: X(B,1) (of class X) 
... 

: 첫 번째 예에서

X("A",2) match { 
    case X("A", 2) => true 
    case X("A", 1) => false 
    case X("A", _) => true 
    case X("B", 2) => false 
} 
+5

, 나는 종종'PartialFunction를 사용합니다. condOpt' ("PartialFunction.condOpt (target) {case X ("A ", p2) => Some (p2)}'의 기본 경우를 쓰는 것을 피하기 위해'PartialFunction._'을 임포트 할 수 있습니다. – Nicolas

+0

나는 그것을 몰랐다. 굉장해! –

+0

너무 간단! 감사! BTW 나는이 예제가 그렇게 쓰여질 수 있음을 알고 있지만이 예제는 단순화되어 있습니다. 추출기의 주요 목적은 쉽게 호출 할 수없는 매개 변수 조합을 캡슐화하는 것입니다. – 7zark7

관련 문제