2015-10-02 4 views
0

Я пытаюсь сопоставить конструктор класса (из набора альтернатив) со списком значений, которые извлекаются из разбора некоторых DSL. Поскольку эти значения являются гетерогенными, я сохраняю их в Array[Any].scala reflection: сопоставление символа с заданным значением

Я использую следующий фрагмент кода, чтобы сделать это:

val myClassSymbol: ru.ClassSymbol = mirror.classSymbol(Class.forName(myClassName)) 
    val cm: ru.ClassMirror = mirror.reflectClass(myClassSymbol) 
    val ctor = myClassSymbol.primaryConstructor.alternatives find { c => 
     val signature: ru.Type = c.typeSignature 
     val constructorParams = signature.paramLists.flatten 
     val constructorParamValues: Seq[Any] = resultOfMyParsing 
     (constructorParamValues.size == constructorParams.size) && ((constructorParams zip constructorParamValues) forall ((pair: (ru.Symbol, Any)) => { 
     val sym = pair._1 
     var param = pair._2 
     ??? // something to match the symbol with the value 
     })) 
    } 
ctor map {c => 
     val ctorm = cm.reflectConstructor(ctor.get.asMethod) 
     ctorm(resultOfMyParsing: _*) 
    } getOrElse { 
     throw new IllegalStateException(s"cannot find ctor for $constructorParamValues") // might be relace with some clever logic as a fallback 
    } 

кто-нибудь представление о том, что заменяющего ??? с? (или придумать лучшее/более простое решение)

Большое спасибо!

ответ

0

Я думаю, что лучшее, что вы можете сделать в целом сравнить классы (в зависимости от типа стирания):

val clazz = mirror.runtimeClass(sym.asTerm.typeSignature) 
clazz.isInstance(param) 

Это нужно будет изменить немного, если вы хотите обработать параметры конструктора-имя по ,

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