La syntaxe Scala a beaucoup de symboles. Étant donné que ces types de noms sont difficiles à trouver en utilisant les moteurs de recherche, une liste complète d'entre eux serait utile.
Quels sont tous les symboles de Scala et que fait chacun d'eux?
En particulier, je voudrais savoir sur ->
, ||=
, ++=
, <=
, _._
, ::
et :+=
.
Réponses:
Je divise les opérateurs, à des fins d'enseignement, en quatre catégories :
Il est donc heureux que la plupart des catégories soient représentées dans la question:
La signification exacte de la plupart de ces méthodes dépend de la classe qui les définit. Par exemple,
<=
onInt
signifie "inférieur ou égal à" . Le premier->
, je vais donner comme exemple ci-dessous.::
est probablement la méthode définie surList
(bien qu'elle puisse être l'objet du même nom), et:+=
est probablement la méthode définie sur différentesBuffer
classes.Alors, voyons-les.
Mots-clés / symboles réservés
Il y a quelques symboles dans Scala qui sont spéciaux. Deux d'entre eux sont considérés comme des mots clés appropriés, tandis que d'autres sont simplement "réservés". Elles sont:
Ils font tous partie de la langue et, en tant que tels, peuvent être trouvés dans n'importe quel texte décrivant correctement la langue, comme la spécification Scala (PDF) elle-même.
Le dernier, le trait de soulignement, mérite une description spéciale, car il est si largement utilisé et a tellement de significations différentes. Voici un exemple:
J'ai probablement oublié une autre signification, cependant.
Méthodes importées automatiquement
Donc, si vous n'avez pas trouvé le symbole que vous recherchez dans la liste ci-dessus, il doit s'agir d'une méthode ou d'une partie de celle-ci. Mais, souvent, vous verrez un symbole et la documentation de la classe n'aura pas cette méthode. Lorsque cela se produit, soit vous regardez une composition d'une ou plusieurs méthodes avec quelque chose d'autre, soit la méthode a été importée dans la portée, ou est disponible via une conversion implicite importée.
Ceux-ci peuvent toujours être trouvés sur ScalaDoc : il suffit de savoir où les chercher. Ou, à défaut, regardez l' index (actuellement cassé le 2.9.1, mais disponible le soir).
Chaque code Scala a trois importations automatiques:
Les deux premiers ne rendent disponibles que les classes et les objets singleton. Le troisième contient toutes les conversions implicites et les méthodes importées, puisqu'il
Predef
s'agit d'un objet lui-même.Regarder à l'intérieur
Predef
montre rapidement quelques symboles:Tout autre symbole sera rendu disponible par une conversion implicite . Regardez simplement les méthodes marquées avec
implicit
qui reçoivent, en tant que paramètre, un objet de type qui reçoit la méthode. Par exemple:Dans le cas ci-dessus,
->
est défini dans la classeArrowAssoc
via la méthodeany2ArrowAssoc
qui prend un objet de typeA
, oùA
est un paramètre de type illimité vers la même méthode.Méthodes courantes
Ainsi, de nombreux symboles sont simplement des méthodes sur une classe. Par exemple, si vous le faites
Vous trouverez la méthode
++
directement sur ScalaDoc for List . Cependant, il existe une convention que vous devez connaître lors de la recherche de méthodes. Les méthodes se terminant par deux points (:
) se lient à droite au lieu de gauche. En d'autres termes, alors que l'appel de méthode ci-dessus équivaut à:Si je l'avais, cela
1 :: List(2, 3)
équivaudrait à:Vous devez donc regarder le type trouvé à droite lorsque vous recherchez des méthodes se terminant par deux points. Considérez, par exemple:
La première méthode (
+:
) se lie à droite et se trouve surList
. La deuxième méthode (:+
) est juste une méthode normale, et se lie à gauche - encore une fois, surList
.Sucres syntaxiques / composition
Voici donc quelques sucres syntaxiques qui peuvent masquer une méthode:
La dernière est intéressante, car toute méthode symbolique peut être combinée pour former une méthode de type affectation de cette façon.
Et, bien sûr, différentes combinaisons peuvent apparaître dans le code:
la source
val c = ex(2)
au lieu deval ex(c) = 2
?val ex(c) = 2
.Une différence (bonne, IMO) entre Scala et d'autres langues est qu'elle vous permet de nommer vos méthodes avec presque n'importe quel caractère.
Ce que vous énumérez n'est pas la «ponctuation» mais des méthodes simples et simples, et en tant que telles, leur comportement varie d'un objet à l'autre (bien qu'il existe certaines conventions).
Par exemple, consultez la documentation Scaladoc pour List , et vous verrez certaines des méthodes que vous avez mentionnées ici.
Quelques points à garder à l'esprit:
La plupart du temps, la
A operator+equal B
combinaison se traduit parA = A operator B
, comme dans les exemples||=
ou++=
.Les méthodes qui se terminent par
:
sont bien associatives, cela signifie queA :: B
c'est effectivement le casB.::(A)
.Vous trouverez la plupart des réponses en parcourant la documentation Scala. Garder une référence ici doublerait les efforts, et cela prendrait du retard rapidement :)
la source
Vous pouvez les regrouper en premier selon certains critères. Dans ce post, je vais simplement expliquer le caractère de soulignement et la flèche droite.
_._
contient un point. Un point dans Scala indique toujours un appel de méthode . Donc, à gauche de la période, vous avez le récepteur, et à droite du message (nom de la méthode)._
Est maintenant un symbole spécial dans Scala. Il y a plusieurs articles à ce sujet, par exemple cette entrée de blog tous les cas d'utilisation. Ici , c'est un raccourci de fonction anonyme , c'est-à-dire un raccourci pour une fonction qui prend un argument et appelle la méthode_
dessus. Ce_
n'est pas une méthode valide, donc vous avez certainement vu_._1
ou quelque chose de similaire, c'est-à-dire invoquer une méthode_._1
sur l'argument de la fonction._1
to_22
sont les méthodes des tuples qui extraient un élément particulier d'un tuple. Exemple:Supposons maintenant un cas d'utilisation pour le raccourci de l'application de fonction. Étant donné une carte qui mappe les entiers aux chaînes:
Wooop, il y a déjà une autre occurrence d'une étrange ponctuation. Le tiret et les caractères supérieurs à, qui ressemblent à une flèche de droite , est un opérateur qui produit un
Tuple2
. Il n'y a donc aucune différence dans le résultat de l'écriture ,(1, "Eins")
ou1 -> "Eins"
seulement, ce dernier est plus facile à lire, en particulier dans une liste de tuples comme l'exemple de carte. Ce->
n'est pas magique, il est, comme quelques autres opérateurs, disponible parce que vous avez toutes les conversions implicites en objetscala.Predef
dans la portée. La conversion qui a lieu ici estOù
ArrowAssoc
a la->
méthode qui crée leTuple2
. Ainsi1 -> "Eins"
est l'appel réelPredef.any2ArrowAssoc(1).->("Eins")
. D'accord. Revenons maintenant à la question d'origine avec le caractère de soulignement:Le trait de soulignement ici raccourcit le code équivalent suivant:
Notez que la
map
méthode d'une carte passe le tuple de clé et de valeur à l'argument de fonction. Comme nous ne nous intéressons qu'aux valeurs (les chaînes), nous les extrayons avec la_2
méthode sur le tuple.la source
->
méthode mais votre phrase "Il n'y a donc aucune différence dans le résultat de l'écriture(1, "Eins")
ou1 -> "Eins"
" m'a aidé à comprendre la syntaxe et son utilisation.En plus des réponses brillantes de Daniel et 0__, je dois dire que Scala comprend les analogues Unicode pour certains des symboles, donc au lieu de
on peut écrire
la source
Concernant
::
il y a une autre entrée Stackoverflow qui couvre le::
cas. En bref, il est utilisé pour construireLists
par « consing » un élément de tête et une liste de queue. C'est à la fois une classe qui représente une liste cons'ed et qui peut être utilisée comme extracteur, mais le plus souvent c'est une méthode sur une liste. Comme le souligne Pablo Fernandez, car il se termine par deux points, il est associatif à droite , ce qui signifie que le récepteur de l'appel de méthode est à droite et l'argument à gauche de l'opérateur. De cette façon, vous pouvez exprimer élégamment le contre en ajoutant un nouvel élément head à une liste existante:Cela équivaut à
L'utilisation comme objet extracteur est la suivante:
Cela ressemble à un opérateur ici, mais c'est vraiment juste une autre façon (plus lisible) d'écrire
Vous pouvez en savoir plus sur les extracteurs dans cet article .
la source
<=
est comme si vous le lisiez: «inférieur ou égal». C'est donc un opérateur mathématique, dans la liste de<
(est inférieur à?),>
(Est supérieur à==
?),!=
(Est égal à?),<=
( N'est pas égal?), (Est inférieur ou égal?), Et>=
(est supérieur à ou égal?).Cela ne doit pas être confondu avec
=>
ce qui est une sorte de double flèche à droite , utilisée pour séparer la liste d'arguments du corps d'une fonction et pour séparer la condition de test dans la correspondance de modèle (uncase
bloc) du corps exécuté lorsqu'une correspondance se produit . Vous pouvez voir un exemple de cela dans mes deux réponses précédentes. Tout d'abord, la fonction utilise:qui est déjà abrégé car les types sont omis. La fonction de suivi serait
et l'utilisation de correspondance de modèle:
la source
Je considère qu'un IDE moderne est essentiel pour comprendre les grands projets de scala. Étant donné que ces opérateurs sont également des méthodes, dans l'idée intellij je viens de contrôler-cliquer ou contrôler-b dans les définitions.
Vous pouvez cliquer avec le bouton droit de la souris sur un opérateur contre (: :) et vous retrouver à la scala javadoc en disant "Ajoute un élément au début de cette liste." Dans les opérateurs définis par l'utilisateur, cela devient encore plus critique, car ils pourraient être définis dans des implicits difficiles à trouver ... votre IDE sait où l'implicite a été défini.
la source
Ajoutant simplement aux autres excellentes réponses. Scala propose deux opérateurs symboliques souvent critiqués, les opérateurs
/:
(foldLeft
) et:\
(foldRight
), le premier étant associatif à droite. Ainsi, les trois déclarations suivantes sont équivalentes:Tout comme ces trois:
la source
Scala hérite de la plupart des opérateurs arithmétiques de Java . Cela inclut au niveau du bit ou
|
(caractère de canal unique), au niveau du bit et&
, au niveau du bit exclusif ou^
, ainsi que logique (booléen) ou||
(deux caractères de canal) et logique et&&
. Fait intéressant, vous pouvez utiliser les opérateurs à caractère uniqueboolean
, de sorte que les opérateurs logiques java'ish sont totalement redondants:Comme indiqué dans un autre article, les appels se terminant par un signe égal
=
sont résolus (si une méthode avec ce nom n'existe pas!) Par une réaffectation:Ce «double contrôle» permet, d'échanger facilement un mutable contre une collection immuable:
la source
true | { println( "Icke" ); true }
⇒ imprime!true || { println( "Icke" ); true }
⇒ n'imprime pas !