scala: использование метода расширения класса на основе макросов вызывает черту по умолчанию impl, если тип экземпляра статически является базовым классом - PullRequest
0 голосов
/ 25 марта 2020

У меня есть черта T, я реализую ее с помощью макроса в классе C. я создаю экземпляр C и вызываю его методы. если тип val, содержащий экземпляр C, равен C - работает как положено. если типом val, содержащим экземпляр C, является 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

1 Ответ

1 голос
/ 25 марта 2020

Макросы Def раскрываются во время компиляции, поэтому поздняя привязка / динамическая диспетчеризация c (что является функцией времени выполнения) для них невозможна.

Во время компиляции неизвестно, что t имеет тип C, во время компиляции известно только, что t имеет тип T.

Подробности здесь: Евгений Бурмако. Объединение метапрограммирования времени компиляции и времени выполнения в Scala https://infoscience.epfl.ch/record/226166/files/EPFL_TH7159.pdf p. 98, §4.6.1 «Наследование»

...