Scala maps -> operator
What does the symbol ->
mean in the context of a Map
in Scala?
Scala’s Predef
class offers an implicit conversion that lets one write
key -> value
as an alternate syntax for the pair (key, value)
.
I read it in Scala开发者_Go百科ByExample but fail to see how this works for Maps.
Here's the implicit conversion:
implicit def any2ArrowAssoc[A](x: A): ArrowAssoc[A] = new ArrowAssoc(x)
This will convert any type into an instance of "ArrowAssoc"
class ArrowAssoc[A](x: A) {
def -> [B](y: B): Tuple2[A, B] = Tuple2(x, y)
}
So when Scala sees
"a"->1
It says "There is no method named '->' on String. Are there any implicit conversions in scope that can give me a type that has a method named '->'?" Predef.scala is automatically in scope, and offers a conversion to ArrowAssoc, which obviously has the '->' method. Scala then essentially converts the above to
any2ArrowAssoc("a").->(1)
This method returns a Tuple2("a", 1) (often called a Pair). Map has a constructor that thats an array (varargs) of Tuple2s, so we're off to races! No magic in the compiler (besides implicit conversion, which is used extensively and for many different purposes), and no magic in Maps constructor.
The ->
operator is a shorthand for associating a key with a value when used in the context of a map. In some languages, you are simply allowed to pass the pair of the key and value (usually with the key in the first position and the value in the second) to the constructor or one of the various methods on a map and it will be handled appropriately -- this is also allowed with Scala maps.
However, Scala also provides the shorthand form of key -> value
, which, as you've discovered, is defined in Predef via an implicit, to make the association more clear. Essentially it's saying: "take the item on the left and map it to the item on the right." You'll notice if you read the definition of the Map object, that it does not define any methods that obviously use this ->
method. Instead, the methods take objects of type Tuple2
(this is a tuple of 2 values: e.g. (item1, item2)
), which Scala implicity converts via the method in Predef.
In some languages, the ->
syntax is defined as part of the language itself, but due to the flexibility of Scala, this is able to be defined simply as a method.
->
is used to couple keys and values for a map. So:
val m = Map(1 -> "one", 2 -> "two", 3 -> "three")
will map the first 3 positive integers into text equivalents (that is, m(1)
will be "one"
, etc.). You could also write it as
val m = Map((1,"one"), (2,"two"), (3,"three"))
but the first way looks nicer, which is why it's provided as an alternative.
As Adam said, ->
is not scala syntax, it is a method of the class ArrowAssoc
. When you write "foo" -> "bar", the compiler inserts a implicit conversion from "foo" to ArrowAssoc instance so that the ->
method can be found.
package scala
object Predef {
class ArrowAssoc[A](x: A) {
def -> [B](y: B): Tuple2[A, B] = Tuple2(x, y)
}
implicit def any2ArrowAssoc[A](x: A): ArrowAssoc[A] =
new ArrowAssoc(x)
...
}
google "“scala rich wrappers” to know more.
精彩评论