Je divise les opérateurs, pour les besoins de l'enseignement, en quatre catégories :
- Mots clés/symboles réservés
- Méthodes importées automatiquement
- Méthodes communes
- Sucres syntaxiques/composition
Il est donc heureux que la plupart des catégories soient représentées dans la question :
-> // Automatically imported method
||= // Syntactic sugar
++= // Syntactic sugar/composition or common method
<= // Common method
_._ // Typo, though it's probably based on Keyword/composition
:: // Common method
:+= // Common method
La signification exacte de la plupart de ces méthodes dépend de la classe qui les définit. Par exemple, <=
en Int
signifie "inférieur ou égal à" . Le premier, ->
Je vais vous donner un exemple ci-dessous. ::
est probablement la méthode définie sur List
(bien qu'il pourrait soit l'objet du même nom), et :+=
est probablement la méthode définie sur divers Buffer
classes.
Alors, voyons-les.
Mots clés/symboles réservés
Certains symboles en Scala sont spéciaux. Deux d'entre eux sont considérés comme des mots-clés appropriés, tandis que les autres sont simplement "réservés". Ce sont les suivants :
// Keywords
<- // Used on for-comprehensions, to separate pattern from generator
=> // Used for function types, function literals and import renaming
// Reserved
( ) // Delimit expressions and parameters
[ ] // Delimit type parameters
{ } // Delimit blocks
. // Method call and path separator
// /* */ // Comments
# // Used in type notations
: // Type ascription or context bounds
<: >: <% // Upper, lower and view bounds
<? <! // Start token for various XML elements
" """ // Strings
' // Indicate symbols and characters
@ // Annotations and variable binding on pattern matching
` // Denote constant or enable arbitrary identifiers
, // Parameter separator
; // Statement separator
_* // vararg expansion
_ // Many different meanings
Ce sont tous partie de la langue et, en tant que telle, elle peut être trouvée dans tout texte décrivant correctement la langue, tel que Spécification Scala (PDF) lui-même.
Le dernier, le trait de soulignement, mérite une description spéciale, car il est très largement utilisé et a de nombreuses significations différentes. En voici un exemple :
import scala._ // Wild card -- all of Scala is imported
import scala.{ Predef => _, _ } // Exception, everything except Predef
def f[M[_]] // Higher kinded type parameter
def f(m: M[_]) // Existential type
_ + _ // Anonymous function placeholder parameter
m _ // Eta expansion of method into method value
m(_) // Partial function application
_ => 5 // Discarded parameter
case _ => // Wild card pattern -- matches anything
f(xs: _*) // Sequence xs is passed as multiple parameters to f(ys: T*)
case Seq(xs @ _*) // Identifier xs is bound to the whole matched sequence
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 méthode. Mais, souvent, vous verrez un symbole et la documentation de la classe ne contiendra pas cette méthode. Dans ce cas, il s'agit soit d'une composition d'une ou plusieurs méthodes avec quelque chose d'autre, soit d'une méthode importée dans le champ d'application, soit d'une méthode disponible via une conversion implicite importée.
Ces peuvent encore être trouvés en ScalaDoc Il faut juste savoir où les chercher. Ou, à défaut, regardez le indice (actuellement cassé sur 2.9.1, mais disponible sur nightly).
Chaque code Scala comporte trois importations automatiques :
// Not necessarily in this order
import _root_.java.lang._ // _root_ denotes an absolute path
import _root_.scala._
import _root_.scala.Predef._
Les deux premiers ne rendent disponibles que les classes et les objets singleton. La troisième contient toutes les conversions implicites et les méthodes importées, puisque Predef
est un objet lui-même.
Regarder à l'intérieur Predef
montrer rapidement quelques symboles :
class <:<
class =:=
object <%<
object =:=
Tout autre symbole sera mis à disposition par le biais d'un conversion implicite . Il suffit de regarder les méthodes étiquetées avec implicit
qui reçoivent, comme paramètre, un objet du type qui reçoit la méthode. Par exemple :
"a" -> 1 // Look for an implicit from String, AnyRef, Any or type parameter
Dans le cas ci-dessus, ->
est défini dans la classe ArrowAssoc
par la méthode any2ArrowAssoc
qui prend un objet de type A
, donde A
est un paramètre de type non borné de la même méthode.
Méthodes communes
Ainsi, de nombreux symboles sont simplement des méthodes sur une classe. Par exemple, si vous faites
List(1, 2) ++ List(3, 4)
Vous trouverez la méthode ++
directement sur la ScalaDoc pour Liste . Cependant, il y a une convention dont vous devez être conscient lorsque vous recherchez des méthodes. Les méthodes se terminant par deux points ( :
) lier à droite au lieu de la gauche. En d'autres termes, alors que l'appel de méthode ci-dessus est équivalent à :
List(1, 2).++(List(3, 4))
Si j'avais, à la place 1 :: List(2, 3)
ce qui équivaudrait à :
List(2, 3).::(1)
Donc vous devez regarder le type trouvé à droite lors de la recherche de méthodes se terminant par deux points. Considérez, par exemple :
1 +: List(2, 3) :+ 4
La première méthode ( +:
) se lie à la droite, et se trouve sur List
. La deuxième méthode ( :+
) est juste une méthode normale, et se lie à la gauche -- encore une fois, sur List
.
Sucres syntaxiques/composition
Voici donc quelques sucres syntaxiques qui peuvent cacher une méthode :
class Example(arr: Array[Int] = Array.fill(5)(0)) {
def apply(n: Int) = arr(n)
def update(n: Int, v: Int) = arr(n) = v
def a = arr(0); def a_=(v: Int) = arr(0) = v
def b = arr(1); def b_=(v: Int) = arr(1) = v
def c = arr(2); def c_=(v: Int) = arr(2) = v
def d = arr(3); def d_=(v: Int) = arr(3) = v
def e = arr(4); def e_=(v: Int) = arr(4) = v
def +(v: Int) = new Example(arr map (_ + v))
def unapply(n: Int) = if (arr.indices contains n) Some(arr(n)) else None
}
val Ex = new Example // or var for the last example
println(Ex(0)) // calls apply(0)
Ex(0) = 2 // calls update(0, 2)
Ex.b = 3 // calls b_=(3)
// This requires Ex to be a "val"
val Ex(c) = 2 // calls unapply(2) and assigns result to c
// This requires Ex to be a "var"
Ex += 1 // substituted for Ex = Ex + 1
Le dernier point est intéressant, car tout La méthode symbolique peut être combinée de cette façon pour former une méthode semblable à celle de l'affectation.
Et, bien sûr, il y a diverses combinaisons qui peuvent apparaître dans le code :
(_+_) // An expression, or parameter, that is an anonymous function with
// two parameters, used exactly where the underscores appear, and
// which calls the "+" method on the first parameter passing the
// second parameter as argument.
4 votes
Et l'index de Staircase 1ère édition, à >> artima.com/pins1ed/livre-index.html#indexanchor
2 votes
Related : caractères d'opérateur vs caractères alphanumériques : stackoverflow.com/questions/7656937/
1 votes
Également, s'il y a des "opérateurs" (qui sont principalement des méthodes, avec quelques noms de classes utilisés de manière infixe) que vous ne trouvez pas dans scalex ou le livre de l'escalier, par exemple " !!", les sources probables sont les scaladocs pour akka, scalaz et sbt
0 votes
Exemple de nom de classe utilisé en infixe (en allemand) >> raichoo.blogspot.com/2010/06/spass-mit-scala-infixtypen.html
1 votes
Concernant la question du filtrage par les moteurs de recherche, symbolhound.com est également une bonne alternative
0 votes
Il existe également d'autres symboles comme .< lorsqu'un opérateur relationnel agit comme une méthode sur un entier, par exemple.