79 votes

Comment fonctionne la magie de la méthode apply() de Scala ?

En Scala, si je définis une méthode appelée apply dans une classe ou un objet de niveau supérieur, cette méthode sera appelée chaque fois que j'ajouterai une paire de parenthèses à une instance de cette classe, et que je mettrai les arguments appropriés pour la méthode apply() entre les deux. Par exemple :

class Foo(x: Int) {
    def apply(y: Int) = {
        x*x + y*y
    }
}

val f = new Foo(3)
f(4)   // returns 25

Donc, en gros, object(args) est juste un sucre syntaxique pour object.apply(args) .

Comment Scala effectue-t-il cette conversion ?

Y a-t-il une conversion implicite définie globalement, similaire aux conversions implicites de type dans l'objet Predef (mais de nature différente) ? Ou s'agit-il d'une magie plus profonde ? Je pose la question parce qu'il semble que Scala favorise fortement l'application cohérente d'un petit ensemble de règles, plutôt que de nombreuses règles avec de nombreuses exceptions. Au départ, cela me semble être une exception.

1 votes

67voto

oxbow_lakes Points 70013

Je ne pense pas qu'il y ait quelque chose de plus profond que ce que vous avez dit à l'origine : c'est juste un sucre syntaxique par lequel le compilateur convertit les données de l'utilisateur en données de l'utilisateur. f(a) en f.apply(a) comme un cas spécial de syntaxe.

Cela peut sembler être une règle spécifique, mais seuls quelques-uns d'entre eux (par exemple, avec l'option update ) permet DSL -et des bibliothèques.

4 votes

J'ajouterais "quand f est un objet (y compris les fonctions)". Lorsque f est une méthode, il n'y a évidemment pas de telle traduction.

2 votes

@AlexeyRomanov : Eh bien, si f est une méthode qui est définie sans liste de paramètres, alors f(a) est en effet interprété comme quelque chose comme val _tmp = f; _tmp.apply(a) . Mais là, on entre vraiment dans le domaine de la division des poils.

20voto

sebasgo Points 2784

C'est en fait l'inverse, un objet ou une classe avec une méthode apply est le cas normal et une fonction est un moyen de construire implicitement un objet du même nom avec une méthode apply. En fait, chaque fonction que vous définissez est un sous-objet de la fonction n (n est le nombre d'arguments).

Voir la section 6.6:Applications des fonctions de la Spécification du langage Scala pour plus d'informations sur le sujet.

0 votes

+1 pour la modification de la spécification du langage Scala. J'ai ajouté le bon emplacement puisque votre numéro de page est périmé.

8voto

Alexey Romanov Points 39124

Je pose la question parce qu'il semble que Scala favorise fortement l'application cohérente d'un ensemble plus restreint de règles, plutôt que de nombreuses règles avec de nombreuses exceptions.

Oui. Et cette règle appartient à ce plus petit ensemble.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X