2012-02-25 76 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实例的东西进行排序?编译器会阻止你在脚下射击自己。