在Scala宏中是否有一种确定类型包的好方法?

在Scala宏中是否有一种确定类型包的好方法?,scala,macros,scala-macros,Scala,Macros,Scala Macros,我正在编写一个宏,需要确定它参数化的类型的包。有可能是这样的: def macroImpl[T: c.WeakTypeTag](c: Context) = { import c.universe._ val typ = weakTypeOf[T] val pkg = typ.typeSymbol.fullName.stripSuffix(s".${typ.typeSymbol.name}") } 但这让人感觉很不舒服。有更好的方法吗?这不需要在宏中,但这里没有任何东西可以阻止这样

我正在编写一个宏,需要确定它参数化的类型的包。有可能是这样的:

def macroImpl[T: c.WeakTypeTag](c: Context) = {
  import c.universe._

  val typ = weakTypeOf[T]
  val pkg = typ.typeSymbol.fullName.stripSuffix(s".${typ.typeSymbol.name}")
}

但这让人感觉很不舒服。有更好的方法吗?

这不需要在
宏中,但这里没有任何东西可以阻止这样做。只要您有一个类型符号,就可以不断检查该类型的
所有者
,直到找到一个包:

def owners[T : WeakTypeTag] = Iterator.iterate(weakTypeOf[T].typeSymbol.owner)(_.owner).takeWhile(!_.isPackageClass)
此迭代器的最后一个元素是包符号。如果您只关心包名,则可以执行以下操作:

def package[T : WeakTypeTag] = owners[T].last.fullName
关于
所有者
属性有一个很好的注释(我的粗体):

符号按层次结构组织。例如,表示方法参数的符号归相应的方法符号所有,方法符号归其封闭类、特征或对象所有,类归包含包所有,依此类推

例如,如果符号没有所有者,因为它引用顶级实体(如顶级包),则其所有者是特殊的
NoSymbol
singleton对象。表示缺少的符号,
NoSymbol
通常在API中用于表示空值或默认值。访问
NoSymbol
的所有者会引发异常。类型提供的通用接口见API文档


weakTypeOf[T].typeSymbol.owner.fullName。如果这个班是一流的,那就行了。否则,您必须反复调用.owner,直到找到Symbol.isPackageClass=true的内容。