2016-03-10 1 views
2

Я использую отражение для получения типа параметра метода, но есть проблема с varargs. Вот мой код:В Scala, как использовать отражение, чтобы получить реальный тип параметров varargs для метода

import reflect.runtime.universe._ 

case class C() { 
    def f(x: String*) = x 
} 

object Main { 
    def main(args: Array[String]): Unit = { 
    val c = C() 
    val r = runtimeMirror(getClass.getClassLoader).reflect(c) 
    val x = r.symbol.typeSignature.member(newTermName("f")) 
    val params = x.asMethod.paramss.head.map { 
     _.typeSignature.typeSymbol 
    } 
    for (param <- params) { 
     println(param) 
    } 
    } 
} 

Результат:

> class <repeated> 

Как я могу получить реальный тип String? Или есть еще способ сделать это?

ответ

0

Использование _.typeSignature.typeArgs.head, потому что String тип аргумента String*, а не его typeSymbol.

+0

Спасибо за помощь, но я не могу найти метод «typeArgs» в TypeSignature, я использую SCALA 2,10 – SleePy

+0

Этот метод был добавлен в 2.11. См. Http://stackoverflow.com/a/15597707/9204 для альтернативы 2.10. –

+0

Работает в 2.11! Спасибо за помощь – SleePy

0

Ваш параметр x является типом String*. Это то, что вы получите по телефону:

_.typeSignature.typeSymbol 

но String* является intrepreted, как Seq[String] (как мы все знаем). Таким образом, называя:

_.typeSignature.typeArgs 

получит вам ваши аргументы типа, то есть ваш желаемый String. КПП. если вы хотите, чтобы доказать, что String* является Seq просто позвонить:

_.typeSignature.erasure 

Таким образом, ваш измененный код должен выглядеть (опуская класса C):

val c = C() 
val r = runtimeMirror(getClass.getClassLoader).reflect(c) 
val x = r.symbol.typeSignature.member(newTermName("f")) 
val params = x.asMethod.paramss.head.map { 
    _.typeSignature.typeArgs 
} 
for (param <- params) { 
    println(param) 
} 

он будет печатать List(String).

Наслаждайтесь

+0

Спасибо за помощь! – SleePy

Смежные вопросы