Scala反射派生包名称

bin*_*lve 5 reflection scala scala-macros

我想计算Scala类的包名称.

下面的代码有效,但似乎有点冗长

def packagename(cls:ru.ClassSymbol):String = {
    def innerPackageName(cls:JavaUniverse#Symbol):List[JavaUniverse#Name] = {
      if(cls.owner != null && cls.owner.isPackage  ) {
         List(cls.name) ::: innerPackageName(cls.owner)
      }
      else {
          List(cls.name)
      }
    }
    val owner: JavaUniverse#Symbol = cls.owner
    innerPackageName(owner).filterNot{_.toString == "<root>"}.reverse.mkString(":")
  }
Run Code Online (Sandbox Code Playgroud)

有一个更好的方法吗?

Eug*_*ako 7

遍历所有者链直到您命中包(或更准确地说是包类)的概念是正确的,但是您发布的代码具有轻微的风格问题.首先,Symbol.fullName为你连接字符串.其次,公开使用反射API所需的魔术名称通常会在API中的某处暴露.

下面是我会怎么做你想要做的(改变什么newTermNameTermName,如果你在斯卡拉2.10.x):

00:08 ~/Projects/Master/sandbox (master)$ cat Test.scala
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => cm}

object Test extends App {
  def packageName(sym: Symbol) = {
    def enclosingPackage(sym: Symbol): Symbol = {
      if (sym == NoSymbol) NoSymbol
      else if (sym.isPackage) sym
      else enclosingPackage(sym.owner)
    }
    val pkg = enclosingPackage(sym)
    if (pkg == cm.EmptyPackageClass) ""
    else pkg.fullName
  }
  println(packageName(typeOf[Test.type].member(TermName("packageName"))))
  println(packageName(cm.staticPackage("scala")))
  println(packageName(cm.staticClass("scala.collection.immutable.List")))
}

00:08 ~/Projects/Master/sandbox (master)$ sr

scala
scala.collection.immutable
Run Code Online (Sandbox Code Playgroud)