Scala "<-" для понимания
-
04-10-2019 - |
Вопрос
Я обнаружил, что Scala всегда имеет «естественное объяснение» к чему-либо. Всегда что-то вроде «Ой, но это просто функция, называемая этим, и этот объект с этим и этим параметром». В некотором смысле ничего не на самом деле компиляторов - магия, как мы его знаем с других языков.
Мой вопрос на <- Оператор, используемый в следующем коде:
for(i <- 0 to 10) println(i)
В этом примере я вижу, что он переписан к чему-то вроде:
0.to(10).foreach((i:Int)=>println(i))
Но это не объясняет, как я Получил в анонимную функцию внутри функции foreach. В точке, где вы пишете я Это не объект, и еще не объявленная переменная. Так что это, и как он переносится на внутреннюю часть Форева?
Я думаю, что я наконец обнаружил что-то, что на самом деле магия компилятора
Спасибо за ваше время.
Уточнить, Мой вопрос: как работает <- оператор работает в 1-й строке кода, поскольку я не является объектом, на котором его можно назвать функцией.
Решение
<-
Является ли определенный языковым символом ключевых слов, как это =>
но в отличием контраст ->
(который является определенным символом). Потому что он является частью базовой скальсы грамматики, ее можно использовать для создания привязки (для i
В вашем примере) что-то не может быть сделано пользовательными конструкциями.
Другие советы
Чтобы увеличить ответ Дэйва, вот схема перевода для «для пониманий» от Scala Language Specification:
Понимание
for (enums) yield e
оценивает выражениеe
Для каждого привязки, генерируемого перечисленными перечетами. Последовательность перечисления всегда начинается с генератора; Это может сопровождаться дополнительными генераторами, определениями стоимости или охранников.Генератор
p <- e
производит привязки из выраженияe
который совпадает каким-то образом против шаблонаp
. Отказ Определение значенияval p = e
связывает имя значенияp
(или несколько имен в шаблонеp
) к результату оценки выраженияe
. Отказ Охранникif e
Содержит логическое выражение, которое ограничивает перечисленные привязки.Точное значение генераторов и охранников определяется перевод на заинтересованность четырех методов:
map
,filter
,flatMap
, а такжеforeach
. Отказ Эти методы могут быть реализованы по-разному для разных типов носителей.Схема перевода следующая. На первом шаге каждый генератор
p <- e
, где P не является неопровержимым (§8.1) для типаe
заменяетсяp <- e.filter { case p => true; case _ => false }
Затем следующие правила наносится неоднократно, пока все понятности не будут устранены.
Надо понимание
for (p <- e) yield e0
переводится вe.map { case p => e0 }
.Надо понимание
for (p <- e) e0
переводится вe.foreach { case p => e0 }
.Надо понимание
for (p <- e; p0 <- e0 . . .) yield e00
, куда . Отказ Отказ это (возможно пустая) последовательность генераторов или охранников, переводится на:e.flatMap { case p => for (p0 <- e0 . . .) yield e00 }
.Надо понимание
for (p <- e; p0 <- e0 . . .) e00
куда . Отказ Отказ это (возможно пустая) последовательность генераторов или охранников, переводится на:e.foreach { case p => for (p0 <- e0 . . .) e00 }
.Генератор
p <- e
сопровождаемый охранникомif g
переводится на один генератор:
p <- e.filter((x1, . . . , xn) => g )
кудаx1
, . . . ,xn
Бесплатные переменныеp
.Генератор
p <- e
сопровождаемый определением значенияval p0 = e0
переводится на следующий генератор паре значений, гдеx
а такжеx0
являются свежими именами:val (p, p0) <- for(x@p <- e) yield { val x0@p0 = e0; (x, x0) }
В этом случае это действительно немного магии компилятора. Перевод с наборы для фильтрации / карты / flatmap Form - это особый кусочек Desugaring, очень похожего на преобразование специальных форм обновления и применения методов.