我正在编写一个宏,需要确定其参数化类型的包。这可能是这样的:
def macroImpl[T: c.WeakTypeTag](c: Context) = {
import c.universe._
val typ = weakTypeOf[T]
val pkg = typ.typeSymbol.fullName.stripSuffix(s".${typ.typeSymbol.name}")
}
但这感觉非常黑客。有更好的方法吗?
答案 0 :(得分:1)
这不一定是macro
,但这里没有任何内容可以排除这种情况。只要您有类型符号,就可以不断检查类型owner
,直到找到包裹为止:
def owners[T : WeakTypeTag] = Iterator.iterate(weakTypeOf[T].typeSymbol.owner)(_.owner).takeWhile(!_.isPackageClass)
此迭代器的最后一个元素是包符号。如果你关心的只是包名,你可以这样做:
def package[T : WeakTypeTag] = owners[T].last.fullName
The documentation on symbol reflection对owner
属性(我的粗体)有一个很好的说明:
符号按层次结构组织。例如,表示方法参数的符号由相应的方法符号拥有,方法符号由其封闭的类,特征或对象拥有,< strong>一个类拥有由一个包含。
如果符号没有所有者,例如,因为它引用顶级实体(例如顶级包),则其所有者是特殊的
NoSymbol
单例对象。表示缺少的符号,NoSymbol
通常在API中用于表示空值或默认值。访问NoSymbol
的所有者会引发异常。有关Symbol
类型提供的常规界面,请参阅API文档。