获取泛型类型的内部类中声明的伴生对象,无需实例。

huangapple go评论61阅读模式
英文:

Get companion object (declared in an inner class) of generic type without instance

问题

I am working on a method which is given only one piece of information: a type that extends ClassTag (this can be changed to TypeTag if strong guarantees are necessary for resolving certain parts of the type). We are not given an instance such that we can use scala.reflect.runtime.currentMirror to obtain a InstanceMirror from the Scala libraries available. We are not given the arguments necessary to construct such an instance. I am only able to obtain a RuntimeClass of this generic type. Scala has the concept of a companion object. I want to check if the companion object of the given generic class T extends a specific trait A, cast that object as that trait, and invoke the method which is overridden by that companion object. The current code to do what I described is below:

def invokeOverridenMethodOfCompanionObject[T : ClassTag]() {
  import scala.reflect.runtime.currentMirror
  import scala.reflect.runtime.universe.NoSymbol

  val runtimeClass = scala.reflect.classTag[T].runtimeClass
  val companion = currentMirror.classSymbol(runtimeClass).companion

  companion match {
    case NoSymbol => // do nothing
    case _ => 
      // The problem is this line
      currentMirror.reflectModule(companion.asModule).instance match {
        case s: A => s.invokeOverridenMethod
        case _ => // do nothing 
      }
  }
}

This approach is almost perfect. The problem is that if the object is not top level i.e. declared within another object or class, this method no longer works. Scala then complains and spits out this error:

object <objectName> is an inner module, use reflectModule on an InstanceMirror to obtain its ModuleMirror

The problem is I am not able to obtain the instance mirror of the symbol/type which owns the companion object. I cannot construct that instance either since I have no arguments to build a dummy constructor either. I also cannot guarantee the existence of a nullary constructor either, so gimmicks using them are off limits as well. Is there a way to accomplish my goal given these constraints?

Edit: I am aware that Java Class can allow a person to search up the method by name and then invoke it. I know this is possible but my solution would require passing around the object later as well. Therefore, it is a must for me to obtain a variable reference directly to the object. You may assume that after the code block above ends, I return the companion object constructed.

英文:

I am working on a method which is given only one piece of information: a type that extends ClassTag (this can be changed to TypeTag if strong guarantees are necessary for resolving certain parts of the type). We are not given an instance such that we can use scala.reflect.runtime.currentMirror to obtain a InstanceMirror from the Scala libraries available. We are not given the arguments necessary to construct such an instance. I am only able to obtain a RuntimeClass of this generic type. Scala has the concept of a companion object. I want to check if the companion object of the given generic class T extends a specific trait A, cast that object as that trait, and invoke the method which is overriden by that companion object. The current code to do what I described is below:

def invokeOverridenMethodOfCompanionObject[T : ClassTag]() {
  import scala.reflect.runtime.currentMirror
  import scala.reflect.runtime.universe.NoSymbol

  val runtimeClass = scala.reflect.classTag[T].runtimeClass
  val companion = currentMirror.classSymbol(runtimeClass).companion

  companion match {
    case NoSymbol =&gt; // do nothing
    case _ =&gt; 
      // The problem is this line
      currentMirror.reflectModule(companion.asModule).instance match {
        case s: A =&gt; s.invokeOverridenMethod
        case _ =&gt; // do nothing 
      }
  }
}

This approach is almost perfect. The problem is that if the object is not top level i.e. declared within another object or class, this method no longer works. Scala then complains and spits out this error:

object &lt;objectName&gt; is an inner module, use reflectModule on an InstanceMirror to obtain its ModuleMirror

The problem is I am not able to obtain the instance mirror of the symbol/type which owns the companion object. I cannot construct that instance either since I have no arguments to build a dummy constructor either. I also cannot guarantee the existence of a nullary constructor either, so gimmicks using them are off limits as well. Is there a way to accomplish my goal given these constraints?

Edit: I am aware that Java Class can allow a person to search up the method by name and then invoke it. I know this is possible but my solution would require passing around the object later as well. Therefore, it is a must for me to obtain a variable reference directly to the object. You may assume that after the code block above ends, I return the companion object constructed.

答案1

得分: 1

它实际上在类及其伴生对象都定义在一个对象内时良好运行

但是不工作的情况(在该scastie中的注释行)是,如果它们被定义在一个_类_内。对于这种情况,我认为没有实例的话,你无法做太多事情,因为属于不同实例的对象是_不同的_(也具有不同的_类型_):(new Baz.Bat == new Baz.Bat) === false

英文:

It actually works fine when the class and its companion are both defined inside an object.

What doesn't work (commented line in that scastie) is if they are defined inside a class. For that, I don't think you can do much without an instance, because the objects belonging to different instances are different (and also have different types): (new Baz.Bat == new Baz.Bat) === false

huangapple
  • 本文由 发表于 2023年6月15日 07:40:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76478229.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定