我有一个特征T,我在C类中用宏实现了它。我创建了一个C的实例并调用它的方法。如果包含C实例的val的类型是C,则可以按预期工作。如果包含C实例的val的类型是T,则调用方法就像调用T.一样
我能想到的描述它的最好方法是scala宏中的"虚拟表损坏",但我不知道这是不是一件事。。。
示例代码:
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
Def宏在编译时进行扩展,因此不可能进行后期绑定/动态调度(这是一项运行时功能(。
在编译时,t
的类型为C
是未知的,在编译时只知道t
的类型为T
。
请在此处查看详细信息:Eugene Burmako。Scala中编译时与运行时元编程的统一https://infoscience.epfl.ch/record/226166/files/EPFL_TH7159.pdf第98页,§4.6.1"继承">