39 votes

Types de paramètres de fonction et =>

Ce que signifie exactement cette déclaration de paramètre de méthode :

def myFunc(param: => Int) = param

Quelle est la signification de => dans la définition supérieure ?

61voto

Tomasz Nurkiewicz Points 140462

C'est ce qu'on appelle pass-by-name . Cela signifie que vous passez une fonction qui devrait retourner Int mais est surtout utilisé pour implémenter l'évaluation paresseuse des paramètres. Il est quelque peu similaire à :

def myFunc(param: () => Int) = param

Voici un exemple. Considérons un answer qui renvoie une fonction Int valeur :

def answer = { println("answer"); 40 }

Et deux fonctions, l'une prenant Int et un autre qui prend Int par nom :

def eagerEval(x: Int)   = { println("eager"); x; }
def lazyEval(x: => Int) = { println("lazy");  x; }

Maintenant, exécutez-les tous les deux en utilisant answer :

eagerEval(answer + 2)
> answer
> eager

lazyEval(answer + 2)
> lazy
> answer

Le premier cas est évident : avant d'appeler eagerEval() answer est évalué et imprime "answer" ficelle. Le deuxième cas est beaucoup plus intéressant. Nous passons en fait une fonction à lazyEval() . Le site lazyEval premières impressions "lazy" et évalue le x (en fait, les appels x passée en paramètre).

Voir aussi

13voto

Wilfred Springer Points 5430

Juste pour être sûr qu'il y a une réponse qui utilise le bon terme : la spécification du langage Scala utilise le terme appel par nom :

Le type d'un paramètre de valeur peut être prefixé par =>, par exemple x : => T . Le type de un tel paramètre est alors le type de méthode sans paramètre => T . Ceci indique que l'argument correspondant n'est pas évalué au moment de l'application de la fonction, mais mais qu'il est évalué à chaque utilisation de la fonction. C'est-à-dire que l'argument est évalué en utilisant appel par nom .

-- Section 4.6.1 de la Spécification du langage Scala

7voto

mo-seph Points 1403

Pour compléter la réponse de Tomasz Nurkiewicz ci-dessus, la différence que je rencontre entre () => Int et => Int est que le second permet d'appeler avec des blocs nus :

scala> def myfunc(f : () => Int ) = println("Evaluated: " + f )
myfunc: (f: () => Int)Unit

scala> def myfunc2(f : => Int ) = println("Evaluated: " + f )
myfunc2: (f: => Int)Unit

scala> myfunc({1})
<console>:9: error: type mismatch;
 found   : Int(1)
 required: () => Int
              myfunc({1})
                  ^

scala> myfunc2({1})
Evaluated: 1

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