В синтаксисе Scala много символов. Поскольку такого рода имена трудно найти с помощью поисковых систем, их полный список будет полезен.
Каковы все символы в Scala, и что делает каждый из них?
В частности, я хотел бы знать о том ->
, ||=
, ++=
, <=
, _._
, ::
, и :+=
.
Ответы:
В целях обучения я делю операторов на четыре категории :
К счастью, в этом вопросе представлено большинство категорий:
Точное значение большинства этих методов зависит от класса, который их определяет. Например,
<=
наInt
означает «меньше или равно» . Первый->
, я приведу в качестве примера ниже.::
Вероятно, это метод, определенный вList
(хотя это может быть объект с тем же именем), и:+=
, вероятно, метод, определенный в различныхBuffer
классах.Итак, давайте посмотрим на них.
Ключевые слова / зарезервированные символы
В Scala есть специальные символы. Два из них считаются правильными ключевыми словами, а другие просто «зарезервированы». Они есть:
Все они являются частью языка и, как таковые, могут быть найдены в любом тексте, который правильно описывает язык, например, в самой спецификации Scala (PDF).
Последнее, подчеркивание, заслуживает особого описания, потому что оно очень широко используется и имеет так много разных значений. Вот пример:
Я, наверное, забыл какой-то другой смысл, хотя.
Автоматически импортированные методы
Итак, если вы не нашли символ, который ищете в списке выше, то это должен быть метод или его часть. Но часто вы увидите какой-нибудь символ, и документация для класса не будет иметь этого метода. Когда это происходит, либо вы просматриваете композицию одного или нескольких методов с чем-то другим, либо метод был импортирован в область действия или доступен через импортированное неявное преобразование.
Их все еще можно найти в ScalaDoc : вам просто нужно знать, где их искать. Или, если это не удалось, посмотрите на индекс (в настоящее время не работает на 2.9.1, но доступен на ночной).
Каждый код Scala имеет три автоматических импорта:
Первые два делают доступными только классы и одноэлементные объекты. Третий содержит все неявные преобразования и импортированные методы, поскольку
Predef
является самим объектом.Заглянув внутрь,
Predef
быстро покажите несколько символов:Любой другой символ будет доступен через неявное преобразование . Достаточно взглянуть на методы, помеченные этим,
implicit
которые получают в качестве параметра объект типа, который получает метод. Например:В приведенном выше случае
->
определяется в классе сArrowAssoc
помощью метода,any2ArrowAssoc
который принимает объект типаA
, гдеA
параметр неограниченного типа для этого же метода.Общие методы
Итак, многие символы - это просто методы класса. Например, если вы делаете
Вы найдете этот метод
++
прямо в ScalaDoc for List . Однако есть одно соглашение, которое вы должны знать при поиске методов. Методы, оканчивающиеся на двоеточие (:
), связываются справа, а не слева. Другими словами, хотя приведенный выше вызов метода эквивалентен:Если бы я имел вместо этого
1 :: List(2, 3)
, это было бы эквивалентно:Поэтому вам нужно взглянуть на тип, найденный справа, при поиске методов, заканчивающихся двоеточием. Рассмотрим, например:
Первый метод (
+:
) привязывается вправо и находится наList
. Второй метод (:+
) является обычным методом и привязывается слева - опять же, вклList
.Синтаксические сахара / состав
Итак, вот несколько синтаксических сахаров, которые могут скрывать метод:
Последний интересен, потому что любой символический метод может быть объединен таким образом, чтобы сформировать метод, подобный присвоению.
И, конечно же, в коде могут появляться различные комбинации:
источник
val c = ex(2)
вместоval ex(c) = 2
?val ex(c) = 2
.Одно (хорошее, IMO) различие между Scala и другими языками состоит в том, что он позволяет вам называть ваши методы практически любым символом.
То, что вы перечисляете, это не «пунктуация», а простые и простые методы, и, как таковые, их поведение варьируется от одного объекта к другому (хотя существуют некоторые соглашения).
Например, проверьте документацию Scaladoc для List , и вы увидите некоторые из методов, которые вы упомянули здесь.
Некоторые вещи, которые нужно иметь в виду:
В большинстве случаев
A operator+equal B
комбинация переводитсяA = A operator B
, как в||=
или в++=
примеры.Методы, которые заканчиваются на
:
правильной ассоциативности, это означает, чтоA :: B
на самом делеB.::(A)
.Большинство ответов вы найдете в документации по Scala. Сохранение ссылки здесь будет дублировать усилия, и это будет быстро отставать :)
источник
Вы можете сгруппировать их сначала по некоторым критериям. В этом посте я просто объясню символ подчеркивания и стрелку вправо.
_._
содержит точку Точка в Scala всегда указывает на вызов метода . Таким образом, слева от периода у вас есть получатель, а справа от него сообщение (название метода). Теперь_
это специальный символ в Scala. Есть несколько сообщений об этом, например, эта запись в блоге все случаи использования. Здесь это ярлык анонимной функции , то есть ярлык для функции, которая принимает один аргумент и вызывает метод_
для него. Сейчас_
это недопустимый метод, поэтому вы наверняка видели_._1
или что-то подобное, то есть вызываете метод_._1
для аргумента функции._1
чтобы_22
те методы , которые извлекают кортежей конкретный элемент кортежа. Пример:Теперь давайте рассмотрим вариант использования ярлыка приложения функции. Дана карта, которая отображает целые числа в строки:
Wooop, есть уже другое возникновение странной пунктуации. Дефис и символы «больше», которые напоминают правую стрелку , являются оператором, который создает
Tuple2
. Таким образом, нет никакой разницы в результатах написания(1, "Eins")
или1 -> "Eins"
только в том, что последние легче читать, особенно в списке кортежей, как пример карты. Это->
не волшебство, оно, как и некоторые другие операторы, доступно, потому что у вас есть все неявные преобразования в объектеscala.Predef
в области видимости. Здесь происходит преобразованиеГде
ArrowAssoc
есть->
метод, который создаетTuple2
. Таким образом1 -> "Eins"
актуален вызовPredef.any2ArrowAssoc(1).->("Eins")
. Хорошо. Теперь вернемся к исходному вопросу с символом подчеркивания:Здесь подчеркивание сокращает следующий эквивалентный код:
Обратите внимание, что
map
метод Map передает кортеж key и value в аргумент функции. Поскольку нас интересуют только значения (строки), мы извлекаем их с помощью_2
метода из кортежа.источник
->
метод, но ваше предложение «Так что нет никакой разницы в результатах написания(1, "Eins")
или1 -> "Eins"
», помогло мне понять синтаксис и его использование.В дополнение к блестящим ответам Даниэля и 0__, я должен сказать, что Scala понимает аналоги Unicode для некоторых символов, поэтому вместо
можно написать
источник
Что касается
::
еще одной записи Stackoverflow, которая охватывает::
дело. Короче говоря, он используется для конструированияLists
путем « объединения » элемента head и списка хвостов. Это и класс, который представляет объединенный список, и его можно использовать в качестве экстрактора, но чаще всего это метод в списке. Как указывает Пабло Фернандес, поскольку он заканчивается двоеточием, он ассоциативно справа , то есть получатель вызова метода находится справа, а аргумент слева от оператора. Таким образом, вы можете элегантно выразить это как добавление нового элемента head к существующему списку:Это эквивалентно
Использование в качестве объекта экстрактора заключается в следующем:
Здесь это выглядит как оператор, но на самом деле это просто еще один (более читаемый) способ записи
Вы можете прочитать больше об экстракторах в этом посте .
источник
<=
это как «читать»: «меньше или равно». Таким образом, это математический оператор в списке<
(меньше чем?),>
(Больше чем?),==
(Равно?),!=
(Не равно?),<=
(Меньше или равно?) И>=
(больше чем или равно?)Это не следует путать с тем,
=>
что является разновидностью двойной правой стрелки , используемой для отделения списка аргументов от тела функции и для отделения условия тестирования в сопоставлении с образцом (case
блоком) от тела, выполняемого при совпадении , Вы можете увидеть пример этого в моих предыдущих двух ответах. Во-первых, использование функции:который уже сокращен, поскольку типы опущены. Следующая функция будет
и использование сопоставления с образцом:
источник
Я считаю, что современная IDE имеет решающее значение для понимания больших проектов Scala. Так как эти операторы также являются методами, по идее я просто нажимаю или нажимаю control-b в определениях.
Вы можете щелкнуть правой кнопкой мыши в операторе cons (: :) и оказаться в scala javadoc, говоря: «Добавляет элемент в начало этого списка». В пользовательских операторах это становится еще более критичным, поскольку они могут быть определены в труднодоступных имплицитах ... ваша IDE знает, где было определено неявное.
источник
Просто добавив к другим отличные ответы. Scala предлагает два часто критикуемых символических оператора,
/:
(foldLeft
) и:\
(foldRight
), первый из которых является правоассоциативным. Таким образом, следующие три утверждения эквивалентны:Как и эти три:
источник
Scala наследует большинство арифметических операторов Java . Это включает в себя побитовый или
|
(одиночный символ канала), побитовый и&
, побитовый исключающий-или^
, а также логический (логический) или||
(два символа канала) и логический-и&&
. Интересно, что вы можете использовать односимвольные операторыboolean
, поэтому логические операторы java'ish полностью избыточны:Как указано в другом посте, вызовы, заканчивающиеся знаком равенства
=
, разрешаются (если метод с таким именем не существует!) Путем переназначения:Эта «двойная проверка» позволяет легко заменять изменяемую на неизменяемую коллекцию:
источник
true | { println( "Icke" ); true }
⇒ печатает!true || { println( "Icke" ); true }
⇒ не печатает!