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)
有一个更好的方法吗?
遍历所有者链直到您命中包(或更准确地说是包类)的概念是正确的,但是您发布的代码具有轻微的风格问题.首先,Symbol.fullName为你连接字符串.其次,公开使用反射API所需的魔术名称通常会在API中的某处暴露.
下面是我会怎么做你想要做的(改变什么newTermName来TermName,如果你在斯卡拉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)