2011-03-04 11 views
8

Quiero comprobar el tipo de los parámetros de un método, pero no sé la mejor manera de hacer esto. Ver mi código:¿Cómo se empareja la clase [X] para diferentes X?

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

Tenga en cuenta el comentario en el código. No sé cómo verificar los tipos de forma scala.

que he probado:

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

Pero no se puede compilar.

puedo usar java-manera de comprobar:

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

Parece que deberíamos utilizarlo en Scala, ¿verdad?


ACTUALIZACIÓN:

Si quiero usar match, que debería escribir así:

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

¿Es la mejor respuesta?

+1

¿Qué quiere decir con '+>' en la última línea? – Andrey

+0

'+>' es probablemente un error tipográfico y debería leer '=>' – michid

+0

Es un error tipográfico, acabo arreglé. Gracias. – Freewind

Respuesta

10

pude hacer que funcione con T como un tipo definiendo los casos como constantes. No compilaría con los literales de clase como la expresión de caso. Proveedores:

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

Todavía no se puede compilar aquí. Porque 't' aquí es una' Clase', no una instancia normal. – Freewind

+0

Actualizado para t como clase. – richj

+2

Tenga en cuenta que esto no funciona en el caso de que 'S' y' I' sean instancias de parámetros diferentes del mismo tipo, p. Ej. 'S = classof [Lista [cadena]]' y 'I = classof [Lista [Int]]' –

7

Puede utilizar ClassManifest.fromClass a manejar correctamente la coacción de primitivas a AnyVals, y cualquier otro tipo de problemas que podría haber encontrarse con caja vs tipos unboxed al conseguir funky con la reflexión.

De esta manera:

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

@Keven, gracias, pero tengo que decir, '<: <' es demasiado difícil para mí ahora :( – Freewind

+0

@ . freewend - es sólo un método de 'ClassManifest' para comprobar si hay una relación subtipo Nada complicado :) –

+0

@freewend - también se puede simplemente usar' '== en lugar de' <: < 'si lo prefiere. No detectará subclases, pero en este ejemplo no es necesario atrapar subclases de todos modos. –

Cuestiones relacionadas