Deux façons de définir des fonctions en Scala. Quelle est la différence?
Ici est un peu Scala session qui définit et tente de certaines fonctions:
scala> def test1(str: String) = str + str;
test1: (str: String)java.lang.String
scala> test1("ab")
res0: java.lang.String = abab
fonctionne très bien.
scala> val test2 = test1
<console>:6: error: missing arguments for method test1 in object $iw;
follow this method with `_' if you want to treat it as a partially applied function
val test2 = test1
^
oups.
scala> val test2 = test1 _
test2: (String) => java.lang.String = <function1>
scala> test2("ab")
res1: java.lang.String = abab
fonctionne bien!
Maintenant, j'ai vu le _
syntaxe lors de pliage (_ + _
, etc). Donc si je comprends bien _
signifie fondamentalement "un argument". Donc test1 _
signifie essentiellement une fonction avec un argument qui est donné à test1
". Mais pourquoi n'est-ce pas exactement le même que juste test1
? Pourquoi est-il une différence si j'ajoute un _
?
Donc, j'ai continué à explorer...
scala> val test3 = (str: String) => str + str
test3: (String) => java.lang.String = <function1>
scala> test3("ab")
res2: java.lang.String = abab
scala> val test4 = test3
test4: (String) => java.lang.String = <function1>
Ici, il fonctionne sans _
! Quelle est la différence entre un def
ed fonction, et un val
ed fonction?
- Rex, je vais économiser un peu de temps. Vous avez déjà répondu à cette question sur la liste de diffusion sur 1/27/2010. C'était une bonne réponse, de sorte que j'ai un signet. scala-programming-language.1934581.n4.nabble.com/...
- Heh, merci 🙂
- Je pense qu'il ya une regrettable confusion au sujet de l'usage du terme de "fonction" / "la définition d'une fonction" à la Scala. Même la Programmation Scala dit que
def
définit une fonction, mais ce n'est pas tout à fait vrai selon votre définition de "fonction". I. e. une méthode qui renvoie un résultat qui est une fonction de ses paramètres, mais la méthode n'est pas une valeur de la fonction ou de la fonction de l'objet. Il serait probablement utile de faire la distinction entre ces deux usages du terme "fonction". - Lire retronyms réponse à ma question similaire, à partir d'avril '10. stackoverflow.com/questions/2720486/... - (ps, je QRd votre avatar, très drôle!!!)
- En bref - la fonction vs méthode
- double possible de les Fonctions de méthodes vs en Scala
InformationsquelleAutor aioobe | 2011-02-15
Vous devez vous connecter pour publier un commentaire.
Il n'y a pas de différence entre un def ed fonction et de val-ed fonction:
Voir? L'ensemble de ces fonctions, ce qui est indiqué par le
X => Y
type qu'ils ont.Voyez-vous un
X => Y
type? Si vous le faites, aller voir un ophtalmologue, car il n'y a aucun. Le type ici est(X)Y
, couramment utilisé pour désigner un méthode.En fait,
test1
,test2
,test3
ettest4
sont toutes les méthodes qui retournent des fonctions.test5
est une méthode qui renvoie unjava.lang.String
. Aussi,test1
partest4
ne prennent pas de paramètres (uniquementtest1
pourrait, de toute façon), alors quetest5
n'.Donc, la différence est assez simple. Dans le premier cas, vous avez essayé d'attribuer une méthode à un val, mais ne remplissez pas les paramètres de la méthode de prendre. Donc, il a échoué, jusqu'à ce que vous avez ajouté une fuite de soulignement, ce qui signifiait tourner ma méthode en fonction.
Dans le second exemple, on avait une fonction, de sorte que vous n'avez pas besoin de faire autre chose.
Une méthode n'est pas une fonction, et vice versa. Une fonction est un objet de l'un des
FunctionN
classes. Une méthode est une poignée pour un morceau de code associé à un objet.Voir à différentes questions sur les méthodes vs fonctions sur un Débordement de Pile.
(X)Y
un type? Oh, et merci pour le nouveau mot.X => Y
parce qu'il a(
et)
autour deString
? (Sinon, je dois regarder pour un oftamologist dans le jaune-pages.) 2) à Partir de votre description, il me semble que les fonctions sont strictement plus générale que les méthodes, et que je pourrais utiliser votretest1
notation au lieu detest5
notation partout? Quel serait l'inconvénient d'être?X => Y
car il n'y a pas de=>
. Les fonctions sont plus lents que les méthodes, et ils ne peuvent pas recevoir les paramètres de type, a été discuté ailleurs sur un Débordement de Pile.scala> val test4 = test2
est-ce volontaire, ou que vous vouliez valtest4 = test3
?La
def
déclare une méthode dans un objet environnant/classe/trait, semblable à la façon dont vous définissez les méthodes en Java. Vous ne pouvez utiliserdef
s dans d'autres objets/classes/traits. Dans le REPL, vous ne pouvez pas voir l'objet environnant parce qu'il est "caché", mais il existe.Vous ne pouvez pas affecter un
def
à une valeur, parce que ledef
n'est pas une valeur - c'est une méthode de l'objet.La
(x: T) => x * x
déclare et instancie un fonction de l'objet, qui existe au moment de l'exécution. La fonction des objets sont des instances de classes anonymes qui s'étendentFunctionN
traits.FunctionN
traits viennent avec unapply
méthode. Le nomapply
est spécial, car il peut être omis. Expressionf(x)
est délactosé enf.apply(x)
.La ligne de fond est - depuis les objets de fonction sont des valeurs de l'exécution qui existent sur le tas, vous pouvez leur attribuer des valeurs, des variables et des paramètres, ou le retour de méthodes comme valeurs de retour.
Pour résoudre le problème de l'attribution des méthodes de valeurs (ce qui peut être utile), la Scala permet d'utiliser le caractère réservé de créer un objet de fonction à partir d'une méthode. Expression
test1 _
dans l'exemple ci-dessus crée une fonction wrapper autour de la méthodetest1
- c'est équivalent àx => test1(x)
.Le trait de soulignement signifie des choses différentes dans des contextes différents. Mais il peut toujours être considéré comme la chose qui irait ici, mais n'a pas besoin d'être nommé.
Lorsqu'il est appliqué à la place de paramètres, l'effet de l'élévation de la méthode à une fonction.
Note, la méthode est devenue une fonction de type (String) => String.
La distinction entre une méthode et une fonction dans la Scala est que les méthodes sont comparables à des traditionnelles méthodes de Java. Vous ne pouvez pas passer comme valeurs. Cependant, les fonctions sont des valeurs dans leur propre droit et peuvent être utilisés comme paramètres d'entrée et les valeurs de retour.
La levée peut aller plus loin:
Soulever cette résultats de la fonction dans une autre fonction. Cette fois de type () => (String) => (String)
De ce que je peux dire, cette syntaxe est équivalente à la substitution de tous les paramètres avec un trait de soulignement explicitement. Par exemple: