2012-02-29 3 views
30

Qu'est-ce exactement que la déclaration de paramètre de méthode signifie:types de paramètres de fonction et =>

def myFunc(param: => Int) = param 

Quel est le sens de => dans la définition supérieure?

+19

Utilisez [Symbol Hound] (http://symbolhound.com) dans le futur. –

+0

duplication possible de [Scala - Que signifie '=> SomeType'?] (Http: // stackoverflow.com/questions/7225308/scala-what-does-sometype-means) –

+0

Je ne sais pas comment je ne l'ai pas trouvé ... Pense que je devrais changer mes lunettes ... :) – PrimosK

Répondre

51

Ceci est ce que l'on appelle passe-par-nom. Cela signifie que vous passez une fonction qui doit renvoyer Int mais est principalement utilisée pour implémenter l'évaluation paresseuse des paramètres. Il est quelque peu similaire à:

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

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

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

Et deux fonctions, l'une prenant Int et une prise Intpar nom:

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

execute Maintenant, tous les deux en utilisant answer:

eagerEval(answer + 2) 
> answer 
> eager 

lazyEval(answer + 2) 
> lazy 
> answer 

Le premier cas est obvi ous: avant d'appeler eagerEval()answer est évalué et imprime "answer" chaîne. Le deuxième cas est beaucoup plus intéressant. Nous passons actuellement une fonction à lazyEval(). Le lazyEval imprime d'abord "lazy" et évalue le paramètre x (en réalité, appelle la fonction x transmise en tant que paramètre).

Voir aussi

+0

Grande explication !!! +1 – PrimosK

+2

Le terme que vous voulez est "passe-par-nom" -pas "passe-par-valeur". Passer par la valeur est quelque chose de tout à fait différent; c'est ce que Java fait avec les primitives. – Destin

+4

Je pense que vous voulez dire "call-by-name", pas "pass-by-name" ou "pass-by-value" (voir la spécification de langue 4.6.1) –

10

Juste pour vous assurer qu'il ya une réponse qui utilise le terme approprié: la Scala spécification du langage utilise le terme appel par nom:

Le type d'un paramètre de valeur peut être prédéfini 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 niveau de l'application de la fonction, mais est plutôt évalué à chaque utilisation dans la fonction. Autrement dit, l'argument est évalué en utilisant appel par le nom.

- Section 4.6.1 du Scala Language Specification

6

Pour ajouter à la réponse de Tomasz Nurkiewicz ci-dessus, la différence que je rencontre entre() => Int et => Int est que le second, on peut 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 
Questions connexes