Così ho questa macro:statico tipo di ritorno di Scala macro
import language.experimental.macros
import scala.reflect.macros.Context
class Foo
class Bar extends Foo { def launchMissiles = "launching" }
object FooExample {
def foo: Foo = macro foo_impl
def foo_impl(c: Context): c.Expr[Foo] =
c.Expr[Foo](c.universe.reify(new Bar).tree)
}
ho detto tre volte che voglio foo
per restituire un Foo
, eppure posso fare quanto segue (in 2.10. 0-RC3):
scala> FooExample.foo
res0: Bar = [email protected]
scala> res0.launchMissiles
res1: String = launching
La stessa cosa succede se rimuovere i parametri di tipo su entrambi c.Expr
. Se voglio davvero assicurarmi che chiunque chiami il numero foo
non riesca a vedere che stanno ottenendo un Bar
, devo aggiungere un attributo di tipo nell'albero stesso.
questo è in realtà abbastanza grande, ciò significa ad esempio che posso puntare una macro a uno schema di qualche tipo e creare una sottoclasse anonima di qualche Vocabulary
classe con metodi membri che rappresentano i termini del vocabolario, e questi saranno disponibili sul l'oggetto restituito.
Mi piacerebbe capire esattamente quello che sto facendo, però, quindi ho un paio di domande. Innanzitutto, qual è il tipo di ritorno per il metodo foo
? È solo disponibile per la documentazione (facoltativa)? Esso vincola chiaramente il tipo di ritorno (ad esempio, non posso cambiare a Int
in questo caso), e se tolgo del tutto ottengo un errore come questo:
scala> FooExample.foo
<console>:8: error: type mismatch;
found : Bar
required: Nothing
FooExample.foo
^
Ma io posso cambiarlo Any
e ricevo ancora un valore statico Bar
quando chiamo foo
.
In secondo luogo, questo comportamento è specificato da qualche parte? Questo mi sembra un insieme abbastanza elementare di problemi, ma non sono stato in grado di cercare una spiegazione o una discussione chiara.
@ som-snytt: Ma mi sarei comunque aspettato che il tipo restituito su "pippo" avesse l'ultima parola (anche se sono anche contento che non lo sia). –
L'annotazione del tipo di ritorno su 'FooExample.foo' è molto bizzarra qui. Questo è altrimenti come mi aspetterei che i macro si comportino. – drstevens
@drstevens: concordato. –