Scala possède à la fois des fonctions et des méthodes. Dans la plupart des cas, nous pouvons ignorer les différences entre elles. Mais parfois, nous devons comprendre leurs différences.

Les méthodes en Scala sont comme les méthodes en Java ; les méthodes font partie d'une classe. Une méthode possède un nom, une signature de type, parfois des annotations sur la méthode, ainsi que le code d'implémentation fonctionnelle (bytecode) de la méthode.

Les fonctions en Scala sont des objets à part entière. Scala utilise 22 traits pour abstraire le concept de fonction. Ces 22 traits vont de Function1 à Function22 :

Comme le montre la figure ci-dessus, Function10 représente : une fonction avec 10 paramètres formels et une valeur de retour de type R (covariant).

En Scala, les fonctions sont en réalité des objets de classes qui héritent de ces traits. Par exemple, on définit une fonction au moyen d'un littéral de fonction :

En fait, la définition de fonction ci-dessus est équivalente à la définition suivante :

Comme Function2 est un trait, il ne peut pas être instancié directement avec new. Lenew Function2[Int,Int,Int](){}ci-dessus définit et instancie en réalité un objet d'une classe qui implémente le trait Function2.

apply est un sucre syntaxique en Scala : lorsqu'on appelle obj() sur un objet obj, le compilateur Scala le convertit en obj.apply() ; lorsqu'on appelle clazz() sur une classe clazz, le compilateur Scala le convertit en clazz_company_obj.apply(), où clazz_company_obj est l'objet compagnon de clazz.

Les différences précises sont résumées comme suit :

1. Une méthode ne peut pas exister comme expression autonome (sauf les méthodes sans paramètres), mais une fonction le peut. Par exemple :

Dans l'exemple ci-dessus, nous avons d'abord défini une méthode m, puis défini une fonction f. Ensuite, nous utilisons le nom de la fonction (la valeur de fonction) comme expression finale. Comme f est lui-même

un objet (un objet implémentant le trait FunctionN), cet usage est parfaitement correct. Mais si nous utilisons le nom de la méthode comme expression finale, cela provoquera une erreur.

2. Une fonction doit avoir une liste de paramètres, alors qu'une méthode peut ne pas avoir de liste de paramètres.

Dans l'exemple ci-dessus, la méthode m1 accepte zéro paramètre, la liste de paramètres peut donc être omise. Mais une fonction ne peut pas omettre la liste de paramètres.

3. Un nom de méthode est un appel de méthode, alors qu'un nom de fonction ne représente que l'objet fonction lui-même.

C'est plus facile à comprendre. Car la variable qui contient le littéral de fonction (aussi appelée nom de fonction ou valeur de fonction) est elle-même un objet d'une classe implémentant le trait FunctionN. Pour appeler la méthode apply de l'objet, il faut utiliser la syntaxe obj(). Par conséquent, ajouter des parenthèses après le nom de la fonction est la façon d'appeler la fonction. Comme suit :

4. Lorsqu'une fonction est nécessaire, si une méthode est passée, l'expansion ETA (conversion d'une méthode en fonction) est automatiquement effectuée.

Si nous affectons directement une méthode à une variable, une erreur sera signalée. Si nous spécifions le type de la variable comme une fonction, alors cela peut passer la compilation. Comme suit :

Bien sûr, nous pouvons aussi forcer une méthode à être convertie en fonction, ce qui utilise les fonctions partiellement appliquées de Scala :

5. Un paramètre par nom est essentiellement une méthode.

Un paramètre par nom est essentiellement une méthode avec une liste de paramètres vide. Comme suit :

Le code ci-dessus définit en fait une méthode m1, et le paramètre de m1 est un paramètre par nom (méthode). Étant donné que pour une méthode sans paramètres, le nom de la méthode est l'appel de méthode , List(x, x) effectue en fait deux appels de méthode.

Parce queList(x,x)deux appels de méthode sont effectués, deux valeurs différentes sont obtenues.

Si nous modifions légèrement la définition de m1 et mettons d'abord x en cache, le résultat sera très différent de celui d'avant.

Article original : https://blog.csdn.net/u012302488/article/details/50543661