2012-06-28 25 views
7

Birden fazla parametre vaka sınıfına karşı eşleşmede kullanmak için bir ekstraktör (ler) yazmayı deniyorum. Basitleştirilmiş örnek: Her çıkarıcı nesneleri istiyorum Scala - extractor unapply confusion

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

p1 için sabit bir değer tanımlamak ve p2, kullanımı tanımlanır. desen eşleştirme için

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

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

... 

I: yöntemi uygulamak ile Örnek (A, B, vb durumda sınıfı ve altsınıfı X olamaz, ve de bir durum olarak X (,) kullanmak isteyen) böyle maç için onları istiyorum:

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 
} 

Ben vs. A, B, içinde unapply yöntemi tanımlamak gerekir biliyorum ama imza ve mantık ne olması gerektiğini iyice karıştı:

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

Yardım, lütfen?

cevap

14

unapply, herhangi birini alır ve ayıklamak istediğiniz herşeyi bir Option döndürür. Senin durumunda bu olacaktır:

dürüst olmak gerekirse, sen ile geldi örneği A ve B olmadan yeniden yazılabilir Ama
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) 
... 

: İlk örnekte

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

, sık sık 'PartialFunction kullanın. unOnline (burada: 'PartialFunction.condOpt (hedef) {case X (" A ", p2) => Bazı (p2)}'; ayrıca, "PartialFunction._" öğesini de içe aktarabilirsiniz. – Nicolas

+0

Bunu bilmiyordum. Korku veren! –

+0

Çok basit! Teşekkürler! BTW Biliyorum bu örnek böyle yazılabilir, ancak bu örnek basitleştirilmiştir. Aspiratörlerin ana amacı, kolayca hatırlanamayan parametre kombinasyonlarını kapsüllemek. – 7zark7