360 votes

Quelle est la fonction d'application dans Scala?

Je n'ai jamais compris l'artificiel unmarshalling et verbing noms ( AddTwo classe a un apply qui ajoute deux!) des exemples.

Je comprends que c'est du sucre syntaxique, donc (j'en ai déduit du contexte) il doit avoir été conçu pour rendre le code plus intuitive.

Quel sens a une classe avec un apply fonction de donner? À quoi sert-il, et à quelles fins est-il code mieux (unmarshalling, verbing noms etc)?

comment est-il utile dans le cas de compagnon de l'objet?

742voto

Vlad Gudim Points 10161

Les mathématiciens ont leur propre peu de drôles de manières, de sorte qu'au lieu de dire "ensuite, nous appelons la fonction f passant x comme un paramètre" comme nous les programmeurs disent, ils parlent de "l'application de la fonction f de son argument x".

En mathématiques et en informatique, l'Appliquer est une fonction qui s'applique fonctions à arguments.
Wikipédia

apply sert le but de combler le fossé entre Orientée Objet et Fonctionnelle des paradigmes en Scala. Chaque fonction Scala peut être représenté comme un objet. Chaque fonction a un OO type: par exemple, une fonction qui prend un Int paramètre et retourne un Int aura OO type d' Function1[Int,Int].

 // define a function in scala
 (x:Int) => x + 1

 // assign an object representing the function to a variable
 val f = (x:Int) => x + 1

Depuis tout est un objet en Scala f peut maintenant être traitée comme une référence à l' Function1[Int,Int] objet. Par exemple, nous pouvons faire appel toString méthode héritée de Any, ce qui aurait été impossible pour une fonction pure, parce que les fonctions n'ont pas de méthodes:

  f.toString

Ou nous pourrions définir un autre Function1[Int,Int] objet en appelant compose méthode f et le chaînage de deux fonctions:

 val f2 = f.compose((x:Int) => x - 1)

Maintenant, si nous voulons réellement exécuter la fonction, ou en tant que mathématicien dire "appliquer une fonction à ses arguments" nous appelons apply méthode sur l' Function1[Int,Int] objet:

 f2.apply(2)

La rédaction 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 ajoutent beaucoup de désordre pour le code, sans ajouter beaucoup d'informations supplémentaires, et il serait agréable d'être en mesure d'utiliser plus de la notation standard, telles que l' f(args). C'est là compilateur Scala étapes et chaque fois que nous avons une référence f à une fonction d'objet et d'écrire f (args) d'appliquer des arguments à l'représenté fonction, le compilateur se développe silencieusement f (args) à l'objet de l'appel de méthode f.apply (args).

Chaque fonction Scala peut être traitée comme un objet, et il fonctionne dans l'autre sens trop - chaque objet peut être considéré comme une fonction, à condition qu'il ait l' apply méthode. De tels objets peuvent être utilisés en fonction de la notation:

// we will be able to use this object as a function, as well as an object
object Foo {
  var y = 5
  def apply (x: Int) = x + y
}


Foo (1) // using Foo object in function notation 

Il existe de nombreux cas d'utilisation quand on aurait envie de traiter un objet comme une fonction. Le scénario le plus courant est un modèle de fabrique. Au lieu d'ajouter l'encombrement du code à l'aide d'une méthode de fabrique, nous avons peut - apply objet à un ensemble d'arguments pour créer une nouvelle instance d'une classe associée:

List(1,2,3) // same as List.apply(1,2,3) but less clutter, functional notation

// the way the factory method invocation would have looked
// in other languages with OO notation - needless clutter
List.instanceOf(1,2,3) 

Donc, apply méthode est juste un moyen pratique de combler le fossé entre les fonctions et les objets en Scala.

63voto

Nicolas Points 11558

Il s'agit de l'idée que vous voulez appliquer à un objet. Le plus précis de l'exemple est celui des usines. Lorsque vous avez une usine, vous souhaitez appliquer paramètre pour créer un objet.

Scala gars idée que, comme cela se produit dans beaucoup de situation, il pourrait être agréable d'avoir un raccourci pour appeler apply. Ainsi, un sucre syntaxique, c'est que, quand vous donnez des paramètres directement à un objet, c'est délactosé comme si vous passer ces paramètres à appliquer la fonction de cet objet:

class MyAdder(x: Int) {
  def apply(y: Int) = y + y
}

val x = new MyAdder(2)
val y = x(4) // equivalent to x.apply(4)

Il est souvent utiliser dans le compagnon objet de fournir une belle usine méthode à une classe ou à un trait de caractère, voici un exemple:

trait A {
  val x: Int
  def myComplexStrategy: Int
}

object A {
  def apply(x: Int): A = new MyA(x)

  private class MyA(val x: Int) extends A {
    val myComplexStrategy = 42
  }
}

De la scala de la bibliothèque standard, vous pourriez regarder comment scala.collection.Seq est mis en œuvre: Seq est un trait de caractère, ainsi new Seq(1, 2) ne compile pas mais merci pour compagnon de l'objet et de l'appliquer, vous pouvez appeler Seq(1, 2) et la mise en œuvre est choisi par le compagnon de l'objet.

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