2012-08-16 16 views
17

ilgili tip bir demet desen eşleştirme: oScala - Aşağıdakilerin sınıf hiyerarşisi vardır

class A 
class B extends A 
class C extends A 

, bu sınıfların örnekleri alır ve bir yöntem yoktur başka bir sınıf, orada olduğu iki durum arasında desen eşleştirme böyle mümkündür: Bu ikinci durumda (B, C) lehine eşleşmesini çözmelidir zaman

class D (one: A, two: A) { 

    def work { 
    (one, two) match { 
     case (o, t): (B, B) => ... blablabla 
     case (o, t): (B, C) => ... blablabla 
     case _ => 
    } 
    } 
} 

Ancak, (B, B) olarak çözülmesi ve C cannot be cast to B o sınıf dökme haricinde çıkageldi dener. Niye ya? Ne yapalım? Bu konuda nasıl gelebilirim?

cevap

26

Bu olsa çalışır: her zaman olduğu gibi türleri silinir

object Matcher extends App { 

    class A 
    class B extends A 
    class C extends A 

    class D(one: A, two: A) { 

    def work { 
     (one, two) match { 
     case (o: B, t: B) => println("B") 
     case (o: B, t: C) => println("C") 
     case _ => 
     } 
    } 
    } 

    val d1 = new D(new B, new B) 
    val d2 = new D(new B, new C) 

    d1.work 
    //B 
    d2.work 
    //C 
} 
+0

Doğru sözdizimini anlamak için çok uğraştım ... Teşekkürler! – Benoit

2

Bu kod çalışmasını yaptım.
İlk olarak sınıf tanımınıza bir vaka ekledim.

case class A 
case class B extends A 
case class C extends A 

İkinci olarak work'u değiştirdim.

class D(one: A, two: A) { 
    def work { 
    (one, two) match { 
     case (o: B, t: B) => println("BB") 
     case (o: B, t: C) => println("BC") 
     case (o: C, t: C) => println("CC") 
     case _ => println("AA") 
    } 
    } 
} 

aldım Şimdi ne olacak:

new D(B(),B()).work  => BB 
new D(B(),C()).work  => BC 
new D(C(),C()).work  => CC 
new D(A(),B()).work  => AA 
case bir başvuru ekler

ve uygulamasını kaldırma yöntemi. Sözdiziminiz doğru değil (derlenmiyor)

+0

Evet, vaka sınıfları ... ama mirasa sahip hatalar var .. Bazen düzelteceklerse çok mutlu olurum ... – noncom

+0

Tamamen seninleyim. –

+1

Bu kod, modern Scala'da derlenmeyecektir, çünkü 2.9'dan beri bu durumda miras yasaklanmıştır. @noncom Bu bir hata değil, bu tasarım –

7

sorun. (B,C), çalışma zamanında Tuple2 olarak silinen Tuple2[B,C] için sözdizimsel şekerdir. Durum bildirimi, (B,C) öğesinin Tuple2 ile eşleştiğini doğrular, ancak daha sonra yayınlayamaz.

one match { 
    case o : B => two match { 
    case p : C => ... 
    case p : B => ... 
    } 
    ... 
} 

Olmayacak, kadar tatlı ama olmayacak:

Senin durumunda

, kolay çözüm yerine bir demet içinde onları sarma yerine, tek tek 'bir' ve 'iki' karşı maç olacaktır aynı sorunlardan muzdarip.

Düzenleme: Aslında, Brian Smith'in çözümüyle gidiyorum - dışarıdan ziyade tuple eşleşiyor. Sorunu benzer bir şekilde önler, ancak daha güzel görünür.