Оператор Scala maps ->
Пожалуйста, объясните, что означает "- > ", примененное к карте в scala, в среднем.
Scala s Predef
класс предлагает неявное преобразование, которое позволяет писать
key → значение в качестве альтернативного синтаксиса для пары (ключ, значение).
Я прочитал его в ScalaByExample, но не вижу, как это работает для карт.
Ответы
Ответ 1
Оператор ->
является сокращением для связывания ключа со значением при использовании в контексте карты. На некоторых языках вам просто разрешается передавать пару ключей и значений (обычно с ключом в первой позиции и значением во втором) на конструктор или один из различных методов на карте, и он будет обрабатываться соответственно - это также допускается с картами Scala.
Однако Scala также предоставляет сокращенную форму key -> value
, которая, как вы обнаружили, определена в Predef через неявное, чтобы сделать связь более понятной. По существу, он говорит: "Возьмите элемент слева и сопоставьте его с элементом справа". Вы заметите, что если вы читаете определение объекта Map, то он не определяет какие-либо методы, которые явно используют этот метод ->
. Вместо этого методы берут объекты типа Tuple2
(это кортеж из двух значений: например, (item1, item2)
), который Scala implicity преобразуется с помощью метода в Predef.
В некоторых языках синтаксис ->
определяется как часть самого языка, но из-за гибкости Scala это можно определить просто как метод.
Ответ 2
Здесь неявное преобразование:
implicit def any2ArrowAssoc[A](x: A): ArrowAssoc[A] = new ArrowAssoc(x)
Это преобразует любой тип в экземпляр "ArrowAssoc"
class ArrowAssoc[A](x: A) {
def -> [B](y: B): Tuple2[A, B] = Tuple2(x, y)
}
Итак, когда Scala видит
"a"->1
В нем говорится: "Нет метода с именем" → "в String. Существуют ли какие-либо неявные преобразования в области видимости, которые могут дать мне тип, который имеет метод с именем" → "? Predef.scala автоматически входит в область действия и предлагает преобразование в ArrowAssoc, у которого, очевидно, есть метод" → ". Scala, то по существу преобразует приведенное выше значение в
any2ArrowAssoc("a").->(1)
Этот метод возвращает Tuple2 ( "a", 1) (часто называемый парами). У карты есть конструктор, который представляет собой массив (varargs) Tuple2s, поэтому мы отправляемся на гонки! Никакой магии в компиляторе (помимо неявного преобразования, которое широко используется и для разных целей) и магии в конструкторе Карт.
Ответ 3
->
используется для соединения ключей и значений для карты. Итак:
val m = Map(1 -> "one", 2 -> "two", 3 -> "three")
отобразит первые 3 положительных целых числа в текстовые эквиваленты (т.е. m(1)
будет "one"
и т.д.). Вы также можете записать его как
val m = Map((1,"one"), (2,"two"), (3,"three"))
но первый способ выглядит более привлекательно, поэтому он предоставлен в качестве альтернативы.
Ответ 4
Как сказал Адам, ->
не синтаксис scala, это метод класса ArrowAssoc
. Когда вы пишете "foo" → "bar", компилятор вставляет неявное преобразование из "foo" в экземпляр ArrowAssoc, чтобы можно было найти метод ->
.
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", чтобы узнать больше.