使用Scala反射API获取内部模块的伴随对象实例
发布时间:2020-12-16 09:28:17 所属栏目:安全 来源:网络整理
导读:我实现了 Get companion object instance with new Scala reflection API中提到的代码(代码来自 https://gist.github.com/xeno-by/4985929). object Reflection { def getCompanionObject(caseclassinstance:Product):Any = { import scala.reflect.runtime.
我实现了
Get companion object instance with new Scala reflection API中提到的代码(代码来自
https://gist.github.com/xeno-by/4985929).
object Reflection { def getCompanionObject(caseclassinstance:Product):Any = { import scala.reflect.runtime.{currentMirror => cm} val classSymbol = cm.classSymbol(caseclassinstance.getClass) val moduleSymbol = classSymbol.companionSymbol.asModule val moduleMirror = cm.reflectModule(moduleSymbol) moduleMirror.instance } } 这适用于任何标准类的案例类.不幸的是在项目的某些类中我得到一个异常:scala.ScalaReflectionException:object Tensor是一个内部模块,在InstanceMirror上使用reflectModule来获取它的ModuleMirror异常非常清楚,所以我尝试按如下方式更改我的代码: object Reflection { def getCompanionObject(caseclassinstance:Product):Any = { import scala.reflect.runtime.{currentMirror => cm} val classSymbol = cm.classSymbol(caseclassinstance.getClass) val moduleSymbol = classSymbol.companionSymbol.asModule val instanceMirror = cm.reflect(caseclassinstance) val moduleMirror = instanceMirror.reflectModule(moduleSymbol) moduleMirror.instance } } 但是现在我得到一个scala.ScalaReflectionException:期望Tensor类的成员,你提供了对象Prototype2.SPL.SPL_Exp.Tensor,我没有找到如何更改代码来解决这个问题.任何帮助是极大的赞赏! 更新:我提供了一些代码以获得更好的重现性: scala> trait SPL { | case class Tensor() | } defined trait SPL scala> val s = new SPL {} s: SPL = $anon$1@165f5a4 scala> val t = s.Tensor() t: s.Tensor = Tensor() scala> object Reflection { /* as in the first code snippet*/} defined module Reflection scala> Reflection.getCompanionObject(t) scala.ScalaReflectionException: object Tensor is an inner module,use reflectModule on an InstanceMirror to obtain its ModuleMirror ... scala> object Reflection { /* as in the second code snippet*/} defined module Reflection scala> Reflection.getCompanionObject(t) scala.ScalaReflectionException: expected a member of class Tensor,you provided object SPL.Tensor ... 解决方法
你应该有一个模块实例.您只能从Spl的镜像获取Tensor符号的镜像.
trait Spl { case class Tensor(s: String) } val spl = new Spl {} val t = spl.Tensor("T") // mirror for module spl val moduleMirror = cm.reflect(spl) // class symbol for Tensor val instanceSymbol = cm.classSymbol(t.getClass) // symbol for companion object val companionSymbol = instanceSymbol.companionSymbol.asModule // mirror for companion object symbol in spl module mirror val companionMirror = moduleMirror.reflectModule(companionSymbol) scala> companionMirror.instance res0: Any = Tensor 您可以使用一些丑陋的魔法获得Spl的实例: val outer = t. getClass. getFields. find(_.getName == """$outer"""). get. get(t) 你不应该这样做. def getCompanionObject(t: Product):Any = { import scala.reflect.runtime.{currentMirror => cm} val outerField = t.getClass.getFields.find(_.getName == """$outer""") val moduleMirror = outerField.map{ _.get(t) }.map{ cm.reflect(_) } val instanceSymbol = cm.classSymbol(t.getClass) val companionSymbol = instanceSymbol.companionSymbol.asModule val companionMirror = moduleMirror. map{ _.reflectModule(companionSymbol) }. getOrElse{ cm.reflectModule(companionSymbol) } companionMirror.instance } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |