J'ai donc eu cette 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)
}
Je l'ai déjà dit trois fois que je veux foo
- retour d'un Foo
, et pourtant, je peux faire ce qui suit (dans 2.10.0-RC3):
scala> FooExample.foo
res0: Bar = Bar@4118f8dd
scala> res0.launchMissiles
res1: String = launching
La même chose se passe si je retire les paramètres de type ni sur c.Expr
. Si je veux vraiment assurez-vous que celui qui appelle, foo
ne peut pas voir ce qu'ils obtiennent un Bar
, j'ai du ajouter un type de nom dans l'arbre lui-même.
C'est en fait assez grande-cela veut dire par exemple que je peux point une macro à un schéma d'une certaine sorte et créer un anonyme sous-classe de certains Vocabulary
classe avec des méthodes membres représentant les termes dans le vocabulaire, et ces derniers seront disponibles sur l'objet retourné.
J'aimerais comprendre exactement ce que je fais, si, si, j'ai un couple de questions. Tout d'abord, qu'est-ce que le type de retour sur l' foo
méthode fait pour? Est-il juste disponible (en option) documentation? C'est clairement la limite le type de retour (par exemple, je ne peux pas la changer en Int
dans ce cas), et si je le supprimer entièrement, j'obtiens une erreur comme ceci:
scala> FooExample.foo
<console>:8: error: type mismatch;
found : Bar
required: Nothing
FooExample.foo
^
Mais je peut changer en Any
et encore obtenir un statiquement typé Bar
quand je l'appelle foo
.
Deuxièmement, est-ce le comportement spécifié quelque part? Cela semble assez élémentaire de questions, mais je n'ai pas été en mesure de rechercher une explication claire ou de la discussion.