Вопрос

Я обнаружил, что 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, очень похожего на преобразование специальных форм обновления и применения методов.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top