2014-01-29 89 views
5

我想計算一個Scala類的包名。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(":") 
    } 

有沒有更好的方式來做到這一點?

回答

5

遍歷所有者鏈直到打包(或更確切地說,包類)爲止的概念是正確的,但是您發佈的代碼存在細微的風格問題。首先,有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 
+0

感謝您的反饋 –

+0

一個問題,我怎麼獲得一個'TermName'似乎在scala.reflect.internal(我在scala 2.10.3中)舉行 –

+0

爲了讓它編譯,我重寫了它,像這樣:https://gist.github.com/picsolvebryan/8707151 –