Je ne l'ai jamais compris à partir des noms artificiels de démêlage et de verbe (une AddTwo
classe en a un apply
qui en ajoute deux!).
Je comprends que c'est du sucre syntaxique, donc (je l'ai déduit du contexte) il doit avoir été conçu pour rendre le code plus intuitif.
Quel sens donne une classe avec une apply
fonction? À quoi sert-il et à quelles fins améliore-t-il le code (démarshalling, verbes, etc.)?
comment cela aide-t-il lorsqu'il est utilisé dans un objet compagnon?
Réponses:
Les mathématiciens ont leurs propres petites manières amusantes, donc au lieu de dire "alors nous appelons la fonction en la
f
passantx
comme paramètre" comme diraient les programmeurs, ils parlent "d'appliquer la fonctionf
à son argumentx
".apply
sert à combler le fossé entre les paradigmes orientés objet et fonctionnels dans Scala. Chaque fonction dans Scala peut être représentée comme un objet. Chaque fonction a également un type OO: par exemple, une fonction qui prend unInt
paramètre et renvoie unInt
aura le type OO deFunction1[Int,Int]
.Puisque tout est un objet dans Scala, vous
f
pouvez maintenant le traiter comme une référence à unFunction1[Int,Int]
objet. Par exemple, nous pouvons appeler unetoString
méthode héritée deAny
, cela aurait été impossible pour une fonction pure, car les fonctions n'ont pas de méthodes:Ou nous pourrions définir un autre
Function1[Int,Int]
objet en appelant lacompose
méthodef
et en enchaînant deux fonctions différentes ensemble:Maintenant, si nous voulons réellement exécuter la fonction, ou comme le dit le mathématicien "appliquer une fonction à ses arguments", nous appellerions la
apply
méthode sur l'Function1[Int,Int]
objet:Écrire
f.apply(args)
chaque fois que vous voulez exécuter une fonction représentée comme un objet est la méthode orientée objet, mais ajouterait beaucoup d'encombrement au code sans ajouter beaucoup d'informations supplémentaires et il serait bien de pouvoir utiliser une notation plus standard, telle commef(args)
. C'est là que le compilateur Scala intervient et chaque fois que nous avons une référencef
à un objet fonction et écrivonsf (args)
pour appliquer des arguments à la fonction représentée, le compilateur se développe silencieusementf (args)
à l'appel de méthode objetf.apply (args)
.Chaque fonction dans Scala peut être traitée comme un objet et cela fonctionne également dans l'autre sens - chaque objet peut être traité comme une fonction, à condition d'avoir la
apply
méthode. De tels objets peuvent être utilisés dans la notation de fonction:Il existe de nombreux cas d'utilisation où nous voudrions traiter un objet comme une fonction. Le scénario le plus courant est un modèle d'usine . Au lieu d'ajouter de l'encombrement au code à l'aide d'une méthode d'usine, nous pouvons nous
apply
opposer à un ensemble d'arguments pour créer une nouvelle instance d'une classe associée:La
apply
méthode n'est donc qu'un moyen pratique de combler l'écart entre les fonctions et les objets dans Scala.la source
class Average[YType](yZeroValue:YType)
. Comment passez-vous YType à partir de son objet puisque les objets ne peuvent pas accepter les paramètres de type?apply
et desunapply
méthodes à un objet compagnon de la classe (entre autres). Ainsi , la définition d' une classe avec une seule ligne comme celui - cicase class Car(make:String, model: String, year: Short, color: String)
permet de produire de nouveaux objets de la classe Car par seulement:val myCar = Car("VW","Golf",1999,"Blue")
. C'est un raccourci pourCar.apply(...)
every object can be treated as a function, provided it has the apply method
- tellement de sens maintenant.Cela vient de l'idée que vous voulez souvent appliquer quelque chose à un objet. L'exemple le plus précis est celui des usines. Lorsque vous avez une usine, vous souhaitez lui appliquer un paramètre pour créer un objet.
Les gars de Scala pensaient que, comme cela se produit dans de nombreuses situations, il pourrait être agréable d'avoir un raccourci pour appeler
apply
. Ainsi, lorsque vous donnez des paramètres directement à un objet, c'est comme si vous passiez ces paramètres à la fonction d'application de cet objet:Il est souvent utilisé dans un objet compagnon, pour fournir une belle méthode d'usine pour une classe ou un trait, voici un exemple:
Dans la bibliothèque standard de scala, vous pouvez voir comment
scala.collection.Seq
est implémenté:Seq
est un trait, doncnew Seq(1, 2)
ne compilera pas mais grâce à l'objet compagnon et appliquez, vous pouvez appelerSeq(1, 2)
et l'implémentation est choisie par l'objet compagnon.la source
Voici un petit exemple pour ceux qui veulent parcourir rapidement
la source