使用反射将特性实现成员引入范围

  • 本文关键字:成员 范围 实现 反射 scala
  • 更新时间 :
  • 英文 :


我使用反射来解析来自类的所有公共变量访问器,这些类通过以下调用扩展了一个名为Component的特性:

def iterate[T <: Component : TypeTag : ClassTag](component: T) {
  ...
  ru.typeOf[T].members.filter(...)
  ...
}

然而,只有当实现组件特性的类类型在调用期间可见时,这才有效:

val myComp: MyComponent = new MyComponent()
iterate(myComp) // works
val myComp: Component = new MyComponent()
iterate(myComp) // Doesn't work, no members of MyComponent found in scope

一种解决方案是在trait中定义实现类型(MyComponent扩展了Component[MyComponent]),但由于我无论如何都在挖掘反射,我想知道MyComponent的变量是否可以从trait后面访问。

我认为您可以从java.lang.Class获得Type。请参阅下面的示例。

╰─$ scala
Welcome to Scala version 2.11.2 (OpenJDK 64-Bit Server VM, Java 1.7.0_65).
Type in expressions to have them evaluated.
Type :help for more information.
scala> :paste
// Entering paste mode (ctrl-D to finish)

import scala.reflect._
import scala.reflect.runtime.universe._
trait Component {
  def parent: Int = 0
}
class MyComponent extends Component {
  def child: Int = 0
}
def printRuntimeMemberNames(component: Component) = {
  val cls = component.getClass
  val mirror = runtimeMirror(cls.getClassLoader)
  val symbol = mirror.staticClass(cls.getName)
  val tpe = symbol.toType
  val members = tpe.members
  val memberNames = members.map(_.name.decodedName.toString)
  println(memberNames.mkString(", "))
}

// Exiting paste mode, now interpreting.
import scala.reflect._
import scala.reflect.runtime.universe._
defined trait Component
defined class MyComponent
printRuntimeMemberNames: (component: Component)Unit
scala> val c: Component = new MyComponent
c: Component = MyComponent@3db7416a
scala> printRuntimeMemberNames(c)
<init>, child, parent, $init$, $asInstanceOf, $isInstanceOf, synchronized, ##, !=, ==, ne, eq, notifyAll, notify, clone, getClass, hashCode, toString, equals, wait, wait, wait, finalize, asInstanceOf, isInstanceOf

最新更新