74 votes

Liste des fonctions "magiques" de Scala

Où puis-je trouver une liste des fonctions "magiques" de Scala, telles que apply , unapply , update , += etc.

Par fonctions magiques, j'entends les fonctions qui sont utilisées par un sucre syntaxique du compilateur, par exemple

o.update(x,y) <=> o(x) = y

J'ai cherché sur Google une combinaison de scala magic et les synonymes de functions mais je n'ai rien trouvé.

Je ne suis pas intéressé par le utilisation de fonctions magiques dans la bibliothèque standard, mais dans laquelle les fonctions magiques existent.

80voto

Daniel C. Sobral Points 159554

Pour autant que je sache :

Getters/setters liés :

apply
update
identifier_=

Correspondance de motifs :

unapply
unapplySeq

Pour les compréhensions :

map
flatMap
filter
withFilter
foreach

Opérateurs préfixés :

unary_+
unary_-
unary_!
unary_~

Au-delà, tout implicite de A à B. Scala convertira également A <op>= B en A = A <op> B si le premier opérateur n'est pas défini, si "op" n'est pas alphanumérique, et si <op>= n'est pas != , == , <= o >= .

Et je ne crois pas qu'il existe un endroit unique où tous les sucres syntaxiques de Scala sont répertoriés.

3 votes

Vous pourriez vouloir ajouter les opérateurs unaires_ ! etc. qui ont été énumérés dans l'un des autres messages, puisque ceci semble être la réponse la plus exhaustive à la question ici :)

1 votes

Qu'est-ce que identifier_= ? Je n'ai jamais vu ça.

0 votes

@StefanEndrullis Essayez ceci : object X { var _x = 0; def x_=(n: Int) { _x = n }; def x = _x }; X.x = 5; println(X.x)

17voto

Daniel Spiewak Points 30706

En plus de update y apply Il existe également un certain nombre d'opérateurs unaires qui (je crois) peuvent être qualifiés de magiques :

  • unary_+
  • unary_-
  • unary_!
  • unary_~

Ajoutez à cela les opérateurs infixes/suffixes ordinaires (qui peuvent être presque n'importe quoi) et vous obtenez un ensemble complet.

Vous devriez vraiment jeter un coup d'œil à la spécification du langage Scala. C'est la seule source faisant autorité en la matière. Elle n'est pas difficile à lire (tant que vous êtes à l'aise avec les grammaires sans contexte), et très facilement consultable. La seule chose qu'elle ne spécifie pas bien est le support XML.

12voto

Yardena Points 1640

Désolé si cela ne répond pas exactement à votre question, mais mon moment WTF préféré jusqu'à présent est @ en tant qu'opérateur d'affectation dans une correspondance de motif. Grâce à une copie souple de "Programming in Scala", j'ai découvert ce que c'était assez rapidement.

En utilisant @, nous pouvons lier n'importe quelle partie d'un motif à une variable, et si la correspondance du motif réussit, la variable capturera la valeur du sous-modèle. Voici l'exemple de Programmation en Scala (Section 15.2 - Liaison des variables) :

expr match {
  case UnOp("abs", e @ UnOp("abs", _)) => e
  case _ =>
}

Si l'ensemble de la correspondance du motif réussit, alors la partie qui correspond à la partie la partie UnOp("abs", _) est rendue disponible comme variable e.

Et ici C'est ce que Programmer en Scala dit à ce sujet.

Ce lien ne fonctionne plus. Ici en est une qui le fait.

0 votes

Pouvez-vous nous expliquer ce que fait l'opérateur @ ?

4voto

Petr Pudlák Points 25113

J'aimerais ajouter qu'il existe également un trait "magique" - scala.Dynamic :

Un trait de marquage qui permet des invocations dynamiques. Instances x de ce trait permettent les invocations de méthodes x.meth(args) pour des noms de méthodes arbitraires meth et des listes d'arguments args ainsi que les accès aux champs x.field pour des noms de champs arbitraires field .

Si un appel n'est pas nativement supporté par x (c'est-à-dire si la vérification de type échoue), il est réécrit selon les règles suivantes :

foo.method("blah")      ~~> foo.applyDynamic("method")("blah")
foo.method(x = "blah")  ~~> foo.applyDynamicNamed("method")(("x", "blah"))
foo.method(x = 1, 2)    ~~> foo.applyDynamicNamed("method")(("x", 1), ("", 2))
foo.field           ~~> foo.selectDynamic("field")
foo.varia = 10      ~~> foo.updateDynamic("varia")(10)
foo.arr(10) = 13    ~~> foo.selectDynamic("arr").update(10, 13)
foo.arr(10)         ~~> foo.applyDynamic("arr")(10)

Depuis Scala 2.10, la définition de sous-classes directes ou indirectes de ce trait n'est possible que si la fonction dynamique du langage est activée.

Donc vous pouvez faire des choses comme

import scala.language.dynamics

object Dyn extends Dynamic {
  def applyDynamic(name: String)(a1: Int, a2: String) {
    println("Invoked " + name + " on (" + a1 + "," + a2 + ")");
  }
}

Dyn.foo(3, "x");
Dyn.bar(3, "y");

3voto

Eastsun Points 9053

Ils sont définis dans la spécification du langage Scala. Pour autant que je sache, il n'y a que trois fonctions "magiques" comme vous l'avez mentionné.

Les scalaires Getter et Setter peuvent également être liés à votre "magie" :

scala> class Magic {
 |     private var x :Int = _
 |     override def toString = "Magic(%d)".format(x)
 |     def member = x
 |     def member_=(m :Int){ x = m }
 | }

defined class Magic

scala> val m = new Magic

m: Magic = Magic(0)

scala> m.member

res14: Int = 0

scala> m.member = 100

scala> m

res15: Magic = Magic(100)

scala> m.member += 99

scala> m

res17: Magic = Magic(199)

0 votes

Si vous pouviez trouver une preuve de cette affirmation, vous répondriez à ma question ;-) J'ai supposé que ce serait dans les spécifications, mais les trouver n'est pas un travail amusant.

2 votes

Spécification du langage Scala : 6.15 Assignations ... Si x est une fonction sans paramètre définie dans un certain modèle, et que ce même modèle contient une fonction setter x_= comme membre, alors l'assignation x = e est interprétée comme l'invocation x_=(e ) de cette fonction setter. De manière analogue, une affectation f .x = e à une fonction sans paramètre x est interprétée comme l'invocation f .x_=(e ). Une affectation f (args) = e avec une application de fonction à gauche de l'opérateur '=' est interprétée comme f .update(args, e ), c'est-à-dire l'invocation d'une fonction de mise à jour définie par f .

0 votes

Je veux dire, la preuve qu'il n'y en a plus.

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