如何为不同的X模式匹配类[X]?

时间:2011-03-04 08:44:20

标签: scala types

我想检查一个方法的参数类型,但我不知道最好的方法。看我的代码:

class X {
    def x(a: Int, b: String) {}
}

val methods = classOf[X].getDeclaredMethods
methods map { m =>
    m.getParameterTypes.toList map { t =>
        println(t.getName)
        // I don't know how to write the following
        if ( the type of t is Int) { do something} 
        else if( the type of t is String ) { do something}
        else { }
    }
}

请注意代码中的注释。我不知道如何用scala方式检查类型。

我试过了:

t match {
    case _:String => println("### is a string")
    case _:Int => println("### is an int")
    case _ => println("### ?")
}

但它无法编译。

我可以使用java-way来检查:

if (t.isAssignableFrom(classOf[String])) // do something
else if(t.isAssignableFrom(classOf[Int])) // do something
else {}

似乎我们应该在scala中使用它,对吧?


更新:

如果我想使用match,我应该这样写:

t match {
     case i if i.isAssignableFrom(classOf[Int]) => println("### is an Int")
     case s if s.isAssignableFrom(classOf[String]) => println("### is a String")
     case _ => println("###?")
}

这是最好的答案吗?

2 个答案:

答案 0 :(得分:10)

通过将case定义为常量,我可以使用t作为类型。它不会使用类文字作为case表达式进行编译。尝试:

val S = classOf[String]
val I = classOf[Int]
t match {
    case S => println("### is a string")
    case I => println("### is an int")
    case _ => println("### ?")
}

答案 1 :(得分:7)

你可以使用ClassManifest.fromClass来正确处理原语对AnyVals的强制攻击,以及任何其他类似的麻烦,当你用反射来获得时髦时,你可能会遇到盒装和未装箱的类型。

像这样:

import reflect.ClassManifest

class Wibble { def method(a:Int, b: String) = () }

for(method <- classOf[Wibble].getDeclaredMethods; paramType <- method.getParameterTypes) {
  ClassManifest.fromClass(paramType) match {
    case m if m <:< ClassManifest.Int => println("Interiffic")
    case m if m <:< ClassManifest.Float => println("Floaty, like butterflies")
    case m if m <:< ClassManifest.Double => println("Or Quits...")
    //todo: all the other AnyVal types...
    case m if m <:< classManifest[String] => println("bleeding edge physics, yeah baby!")
    //...and a default condition
  }
}