【发布时间】:2020-03-25 10:27:04
【问题描述】:
我有一个特质T, 我用 C 类中的宏实现它。 我创建了一个 C 实例并调用它的方法。 如果包含 C 实例的 val 的类型是 C - 按预期工作。 如果包含 C 实例的 val 的类型是 T - 像 T 一样调用方法。
我能想出的最好的描述方式是 scala-macros 中的“虚拟表损坏”,但我不知道这是否是一回事......
示例代码:
Type in expressions for evaluation. Or try :help.
scala>
scala>
scala> import language.experimental.macros
import language.experimental.macros
scala>
scala>
scala> trait T { def doSomething(): Unit = println ("trait") }
defined trait T
scala>
scala>
scala> import scala.reflect.macros.Context
import scala.reflect.macros.Context
scala>
scala>
scala> object Macro {
| def doSomething(c: Context)(): c.universe.Tree = {
| import c.universe._
| q"""println ("macro")"""
| }
| }
warning: there was one deprecation warning (since 2.11.0); for details, enable `:setting -deprecation' or `:replay -deprecation'
defined object Macro
scala>
scala>
scala> class C extends T { override def doSomething(): Unit = macro Macro.doSomething }
defined class C
scala>
scala> val c: C = new C()
c: C = C@3bd1883a
scala> c.doSomething()
macro
scala>
scala> val t: T = new C()
t: T = C@4079fec7
scala> t.doSomething()
trait
【问题讨论】:
-
我的实际用例是为 scala-logging 贡献一个 PR,我希望通过 2 个不同的宏实现来实现基本特征“ALogger”,并希望记录器的消费者能够抽象地说他们有 ALogger,但是记录器稍后通过 Mixin 或继承来确定。 github.com/lightbend/scala-logging/pull/212
标签: scala scala-macros