【发布时间】:2023-01-25 02:37:16
【问题描述】:
我有一个 Scala 反射符号。
val symbol = scala.reflect.api.Symbol
我怎样才能投射一个物体
val obj: Any
该符号的类型?
我问的原因是我有一个隐式方法将 Map[String, Any] 转换为 Scala 案例类,但同时我想在每个字段上进行转换。
TODO 部分是我要转换类型的地方。
object MapStringAnyOps {
implicit class MapStringAnyOps(m: Map[String, _]) {
def toCaseClass[T: TypeTag : ClassTag]: T = {
val rm = runtimeMirror(classTag[T].runtimeClass.getClassLoader)
val destType = typeOf[T]
val classTest = destType.typeSymbol.asClass
val classMirror = rm.reflectClass(classTest)
val constructor = destType.decl(termNames.CONSTRUCTOR).asMethod
val constructorMirror = classMirror.reflectConstructor(constructor)
val constructorArgs = constructor.paramLists.flatten.map((param: Symbol) => {
val paramName = param.name.toString
if (param.typeSignature <:< typeOf[Option[Any]])
m.get(paramName) **// TODO in here, I can to cast this value of Any into the proper type of this field, but I only have Symbol so I can't simply use asInstanceOf[T]**
else
m.getOrElse(paramName, throw new IllegalArgumentException("Map is missing required parameter named " + paramName))
})
try {
constructorMirror(constructorArgs: _*).asInstanceOf[T]
} catch {
case e: java.lang.IllegalArgumentException =>
throw new java.lang.IllegalArgumentException(s"Error mapping to class constructor:\n Casting from row: ${constructorArgs.map(r => r.getClass.getName).mkString(",")}, to constructor: ${constructor.paramLists.flatten.map(r => r.typeSignature.toString).mkString(",")}", e)
}
}
}
}
【问题讨论】:
标签: scala reflection scala-reflect