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

Fre*_*ind 8 types scala

我想检查一个方法的参数类型,但我不知道这样做的最佳方法.看我的代码:

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 { }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

我试过了:

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

但它无法编译.

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

if (t.isAssignableFrom(classOf[String])) // do something
else if(t.isAssignableFrom(classOf[Int])) // do something
else {}
Run Code Online (Sandbox Code Playgroud)

看来我们应该在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("###?")
}
Run Code Online (Sandbox Code Playgroud)

这是最好的答案吗?

ric*_*chj 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("### ?")
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,在"S"和"I"是同一类型的不同参数化实例的情况下,这不起作用,例如`S = classOf [List [String]]`和`I = classOf [List [Int]]` (2认同)
  • 我设法使用警卫制作oneliner:`case x if x == classOf [String]` (2认同)

Kev*_*ght 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
  }
} 
Run Code Online (Sandbox Code Playgroud)