Scala反射搜索?

4

作为一种思考练习,我想知道是否有可能创建一个Scala特质,在当前对象中进行深度搜索以查找其他符合该定义的项,并调用它们。例如:

trait CanDebug { this =>

  def depthFirstDebug(level:Int) {
    for ( x<-(this object search matching type CanDebug)) {
      x.depthFirstDebug(level+1)

    }
    println("level "+level+" "+this.toString)
  }

}

case class A (s:String) extends CanDebug 

class B extends CanDebug {
  val a1 = A("Hello")      //automatically located by CanDebug by it's type
  val a2 = A("World")
  override def toString = "Start"
}

val b =new B
b.depthFirstDebug(0)

输出以下内容:

一级 Hello
一级 World
零级 Start

使用 Scala 2.10.2,我相信可以使用反射实现,但我不确定具体的操作。谢谢

1个回答

3

您可以使用镜像来反射this,然后调用所需的方法:

import scala.reflect.runtime.universe._
import scala.reflect.runtime.currentMirror

def depthFirstDebug(level:Int) {
  val mirror = currentMirror.reflect(this)
  val tpe = mirror.symbol.typeSignature

  for {
    m <- tpe.members
    if  m.typeSignature <:< typeOf[CanDebug]
    if  m.isTerm
    if !m.isMethod
  } {
    val fld = mirror.reflectField(m.asTerm)
    fld.get.asInstanceOf[CanDebug].depthFirstDebug(level + 1)
  }
  println("level "+level+" "+this.toString)
}

现在您可以:
val b =new B
b.depthFirstDebug(0)

这将为您提供:

level 1 A(World)
level 1 A(Hello)
level 0 Start

太好了!非常感谢提供的信息,似乎有很多关于Scala反射的资料都假定读者已经掌握了高级知识...而我的Scala书籍还没有跟上2.10版本的基础知识学习进度! - LaloInDublin
在最新的Scala版本2.10.2中,Intellij存在一些严重的问题,是什么原因呢?object runtime不是reflect包的成员。 import scala.reflect.runtime.universe ^ - LaloInDublin
2
找到了.. Intellij默认似乎排除了几个Scala JAR包,只需将其添加为依赖项.. scala-reflect.jar - LaloInDublin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接