Я провожу некоторые эксперименты с Witness
и теперь пытаюсь понять, как это работает. Рассмотрим следующий пример:
import shapeless.syntax.singleton._
import shapeless.labelled.FieldType
import shapeless.Witness
def main(args : Array[String]): Unit = {
println(getTaggedValue("xxx" ->> 32))
println(getTaggedValue("yyy" ->> 44))
}
def getTaggedValue[TypeTag, Value](kt: FieldType[TypeTag, Value])
(implicit witness: Witness.Aux[TypeTag]): TypeTag = witness.value
Как и ожидалось, программа печатает
xxx
yyy
Я попытался понять, как были получены эти значения xxx
и yyy
, и напечатал фактический байт-код функции main
:
62: getstatic #69 // Field scala/Predef$.MODULE$:Lscala/Predef$;
65: ldc #71 // String xxx
67: invokevirtual #75 // Method scala/Predef$.println:(Ljava/lang/Object;)V
70: getstatic #69 // Field scala/Predef$.MODULE$:Lscala/Predef$;
73: ldc #77 // String yyy
75: invokevirtual #75 // Method scala/Predef$.println:(Ljava/lang/Object;)V
Как видно, все эти Witness
-трюки не представлены. Неявный Witness.Aux[TypeTag]
пришел из implicit def apply[T]: Witness.Aux[T] = macro SingletonTypeMacros.materializeImpl[T]
Как это работает на самом деле? Компилятор оптимизировал вызов этих методов? Или это было сделано через macro
?
getTaggedValue
,Witness.mkWitness
... На Scala 2.13.1. На 2.12.10 я теперь вижу байт-код, похожий на ваш. Очень странный. - person Jasper-M   schedule 19.12.2019shapeless 2.3.3
иLigthbend Scala 2.12.9
. Какие версии вы используете? - person Some Name   schedule 19.12.2019