I have a trait T, I implement it with macro in class C. i create an instance of C and invoke its methods. if the type of the val containing an instance of C is C - works as expected. if the type of the val containing an instance of C is T - invokes methods as if T.
best way to describe it that i can come up with is "virtual table broken" in scala-macros, but i don't know if that's a thing...
example code:
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 macros are expanded at compile time so late binding / dynamic dispatch (which is a runtime feature) is impossible for them.
At compile time it's unknown that t
has type C
, at compile time it's only known that t
has type T
.
See details here: Eugene Burmako. Unification of Compile-Time and Runtime Metaprogramming in Scalahttps://infoscience.epfl.ch/record/226166/files/EPFL_TH7159.pdf p. 98, §4.6.1 "Inheritance"
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.