scala:如果实例类型是静态基础 class,则使用基于宏扩展 class 的方法调用 trait default impl
scala: using method of extending class based on macros invokes trait default impl if type of instance is statically the base class
我有一个特质T,
我在 class C 中用宏实现它。
我创建了一个 C 实例并调用了它的方法。
如果包含 C 实例的 val 的类型是 C - 按预期工作。
如果包含 C 实例的 val 的类型是 T - 调用方法就好像 T.
我能想出的最好的描述方式是 "virtual table broken" 在 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
Def 宏在编译时扩展,因此后期绑定/动态分派(这是一项运行时功能)对它们来说是不可能的。
在编译时不知道 t
的类型为 C
,在编译时只知道 t
的类型为 T
.
在此处查看详细信息:
尤金布尔马科。 Scala 中编译时和运行时元编程的统一
https://infoscience.epfl.ch/record/226166/files/EPFL_TH7159.pdf
p. 98,§4.6.1 "Inheritance"
我有一个特质T, 我在 class C 中用宏实现它。 我创建了一个 C 实例并调用了它的方法。 如果包含 C 实例的 val 的类型是 C - 按预期工作。 如果包含 C 实例的 val 的类型是 T - 调用方法就好像 T.
我能想出的最好的描述方式是 "virtual table broken" 在 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
Def 宏在编译时扩展,因此后期绑定/动态分派(这是一项运行时功能)对它们来说是不可能的。
在编译时不知道 t
的类型为 C
,在编译时只知道 t
的类型为 T
.
在此处查看详细信息: 尤金布尔马科。 Scala 中编译时和运行时元编程的统一 https://infoscience.epfl.ch/record/226166/files/EPFL_TH7159.pdf p. 98,§4.6.1 "Inheritance"