Próbuję określić typ parametru przekazywany do makra w czasie kompilacji. Wydaje się działać, gdy używam <:<
, ale nie wtedy, gdy używam =:=
. Nie jestem pewien dlaczego. Czy ktoś może wskazać mi właściwy kierunek? Podałem przykładowy kod poniżej.Dlaczego wpisuje się błąd równości, ale w tym makrze wpisuje się poprawność zgodności?
To makro:
import language.experimental.macros
import scala.reflect.macros.Context
object Macros {
def say(param: Any): Unit = macro impl
def impl(c: Context)(param: c.Expr[Any]): c.Expr[Unit] = {
if (param.actualType.<:<(c.universe.typeOf[String])) {
c.universe.reify { printf("string: %s\n", param.splice) }
} else if (param.actualType.<:<(c.universe.typeOf[Int])) {
c.universe.reify { printf("int: %d\n", param.splice) }
} else {
c.universe.reify { printf("any: %s\n", param.splice) }
}
}
}
Wywoływana przez ten kod:
object Test extends App {
Macros.say("Hi")
Macros.say(1)
Macros.say(Blah)
}
case object Blah
Powroty:
string: Hi
int: 1
any: Blah
Ale jeśli sprawdzeniu równości typu (=:=
) zamiast makro zwrotów:
any: Hi
any: 1
any: Blah
Każda pomoc będzie bardzo doceniana.
+1, pokazał mi do niego. Warto zauważyć, że 'Int (1)' jest nazywane _singleton type_, tzn. Typem, który jest tylko zamieszkany przez wartość '1', i że' =: = 'będzie działało zgodnie z oczekiwaniami z nie-literalnymi argumentami (np.' Val i = 1; Macros.say (i) '). –
Brilliant. Dziękuję wam obu! –