scala:如果实例类型是静态基类,则使用基于宏扩展类的方法调用trait默认impl



我有一个特征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"继承">

最新更新