Как сопоставить шаблон Class [X] для разных X? - PullRequest
8 голосов
/ 04 марта 2011

Я хочу проверить тип параметров метода, но я не знаю лучший способ сделать это.Смотрите мой код:

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-способ для проверки:

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 ]

10 голосов
/ 04 марта 2011

Я мог бы заставить его работать с 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("### ?")
}
7 голосов
/ 04 марта 2011

Вы можете использовать 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
  }
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...