实现包内的实现

时间:2018-05-12 17:05:11

标签: scala scala-macros

当使用宏来实现特征的实现时,我想在一个包中创建实现,以便它可以访问其他包私有类。

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] {}

2 个答案:

答案 0 :(得分:0)

宏必须扩展为AST,它将在宏调用所在的位置进行编译。由于package声明are only allowed at top-level,并且方法调用不允许,因此扩展树无法在另一个包中创建任何内容。

答案 1 :(得分:0)

正如Alexey Romanov指出的那样,这是不可能的。仍然如果你只调用几种方法(如果你使用宏,很可能就是这样),一种可能的(但不是完美的)解决方法可能是创建一个公共抽象类或特征,扩展目标特征并“发布”所有必需的包私有方法为protected个代理。因此,您可以通过从该抽象类继承而不是从trait继承宏来创建实例。显然这个技巧有效地“泄漏”了这些方法给任何人但是多亏了反思任何人都可以调用任何方法,如果他真的想要的话。滥用这个技巧将表现为故意努力绕过你的分离作为反思的使用。