当使用宏来实现特征的实现时,我想在一个包中创建实现,以便它可以访问其他包私有类。
trait MyTrait[T]
object MyTrait {
implicit def materialize[T]: MyTrait[T] = macro materializeImpl[T]
def materializeImpl[T : c.WeakTypeTag](c: blackbox.Context): c.Expr[MyTrait[T]] = {
val tt = weakTypeTag[T]
c.Expr[MyTrait[T]](q"new MyTrait[$tt] {}")
}
}
是否可以在特定包中实现new MyTrait[$tt] {}
?
答案 0 :(得分:0)
宏必须扩展为AST,它将在宏调用所在的位置进行编译。由于package
声明are only allowed at top-level,并且方法调用不允许,因此扩展树无法在另一个包中创建任何内容。
答案 1 :(得分:0)
正如Alexey Romanov指出的那样,这是不可能的。仍然如果你只调用几种方法(如果你使用宏,很可能就是这样),一种可能的(但不是完美的)解决方法可能是创建一个公共抽象类或特征,扩展目标特征并“发布”所有必需的包私有方法为protected
个代理。因此,您可以通过从该抽象类继承而不是从trait继承宏来创建实例。显然这个技巧有效地“泄漏”了这些方法给任何人但是多亏了反思任何人都可以调用任何方法,如果他真的想要的话。滥用这个技巧将表现为故意努力绕过你的分离作为反思的使用。