简体   繁体   English

标量反射:将符号与给定值匹配

[英]scala reflection: matching a symbol against a given value

I'm trying to match a class constructor (from the set of alternatives) against a list of values that are retrieved from parsing some DSL. 我正在尝试将类构造函数(从替代方法集中)与从解析某些DSL检索到的值列表进行匹配。 As these values are heterogeneous, I store them in an Array[Any] . 由于这些值是异构的,因此将它们存储在Array[Any]

I'm using the following piece of code to do so: 我正在使用以下代码来做到这一点:

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
    }

Has anyone an idea what to replace the ??? 有谁知道替换什么??? with? 与? (or come up with a better/simpler solution altogether) (或完全提出更好/更简单的解决方案)

Many thanks in advance! 提前谢谢了!

I think that the best you can do in general is to compare classes (due to type erasure): 我认为一般而言,您能做的最好的就是比较类(由于类型擦除):

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

This will need to be modified a bit if you want to handle by-name constructor parameters. 如果要处理按名称的构造函数参数,则需要对此进行一些修改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM