Freewind
Freewind

Reputation: 198318

How to pattern-match Class[X] for different X?

I want to check the type of the parameters of a method, but I don't know the best way to do this. See my code:

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 { }
    }
}

Please note the comment in the code. I don't know how to check the types in scala way.

I've tried:

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

But it can't be compiled.

I can use java-way to check:

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

It seems we should use it in scala, right?


UPDATE:

If I want to use match, I should write like this:

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("###?")
}

Is it the best answer?

Upvotes: 8

Views: 7886

Answers (2)

richj
richj

Reputation: 7529

I could make it work with t as a type by defining the cases as constants. It wouldn't compile with the class literals as the case expression. Try:

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

Upvotes: 10

Kevin Wright
Kevin Wright

Reputation: 49705

You can use ClassManifest.fromClass to correctly handle the coercion of primitives to AnyVals, and any other such troubles you might have encountering boxed vs unboxed types when getting funky with reflection.

Like this:

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
  }
} 

Upvotes: 7

Related Questions