2012-02-25 70 views
3
所有派生類

我想實現這樣的事情:模式對基礎類進行匹配,並在斯卡拉

def a(b: Any) = { 
    b match { 
    case x: Seq[String] => println("x") 
    } 
} 

// somewhere else 

a(List("b")) 

正如我很樂意看到「X」正在打印的結果,我不噸。

基本上我想匹配一個類型/特徵,並覆蓋所有類型派生自/實現此類型/特徵的對象,其特徵爲Seq並且事先知道類型參數。 因爲我是一個Scala新手,我很困難,但是。

想法?

+2

嗯,我不知道你,但它肯定會在這裏打印'x'。 – 2012-02-25 13:29:38

回答

5

由於類型擦除,您無法檢查參數化類型。看到這個問題,爲什麼會出現一個警告:Warning about an unchecked type argument in this Scala pattern match?

另一個問題及其答案告訴你如何解決是:How do I get around type erasure on Scala? Or, why can't I get the type parameter of my collections?

不過你的代碼工作正常,當你不覈對類型參數:

scala> List("a") match { case _: Seq[_] => 1 case _ => 2 } 
res0: Int = 1 
+4

*您無法檢查參數化類型*有一個小例外 - 數組 – 2012-02-25 10:56:51

1

我的第一個想法是,你做錯了。而不是模式匹配,這裏你想要的是一個類型類,或者其他一些機制(類方法),它們可以執行基於類型的動態分派。使用模式匹配來執行您自己的基於類型的調度會導致混亂的代碼和thwarts類型的安全性。

下面是一個在Scala中的類型類的快速常見示例。首先,定義一個特徵表明該類的類型都有一個共同點:

trait Ord[T] { def compare (x: T, y: T): Boolean } 

在你的情況,你會希望a方法是性狀的方法。然後,對於要屬於類類型每種類型,爲其創建一個隱含的對象:

implicit object ordInt extends Ord[Int] { 
    def compare (x: Int, y: Int) = x <= y 
} 

在這裏,我做我的Int類型Ord類的一個實例。現在您可以編寫依賴於您的類型類提供的接口的方法。該方法應該含蓄地接受特定類型的類對象,像這樣:

def sort[T](xs: List[T])(implicit ord: Ord[T]) = { 

然後你可以通過調用它的隱含對象上使用的類型類的特殊方法。

def sort[T](xs: List[T])(implicit ord: Ord[T]) = { 
    def insert(y: T, ys: List[T]): List[T] = ys match { 
    case Nil => List(y) 
    case z :: zs => 
     if (ord.compare(y,z)) { y::z::zs } // <--- here I use ord.compare 
     else { z :: insert(y, zs) } 
    } 
    xs.foldRight(List[T]())(insert _) 
} 

瞧!我們有類型指示的調度,而不會丟失類型安全。想要對Ints列表進行排序?沒問題。試圖對沒有Ord實例的東西進行排序?編譯器會阻止你在腳下射擊自己。