Scala for Backend Engineering & Functional Programming · Урок

Option в for-comprehension

Объединяйте варианты в цепочку

Урок 4 из 413 шагов

«Option в for-comprehension» — бесплатный урок Scala for Backend Engineering & Functional Programming на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Scala for Backend Engineering & Functional Programming, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Scala for Backend Engineering & Functional Programming содержит 4 уроков всего.

Чистая цепочка Options

Цепочка из нескольких вызовов flatMap и map может быть трудной для чтения. Цикл for с вычислением результата в Scala предлагает более понятный синтаксис для того же действия.

Это синтаксический сахар, который компилятор преобразует в вызовы flatMap и map.

Базовый цикл for с вычислением результата

Внутри for { ... } yield ... каждая конструкция x <- option извлекает значение, если оно присутствует. Конструкция yield создаёт итоговый результат.

Если каждый Option является Some, Вы получаете Some с результатом.

object Main {
  def main(args: Array[String]): Unit = {
    val a: Option[Int] = Some(3)
    val b: Option[Int] = Some(4)
    val sum = for {
      x <- a
      y <- b
    } yield x + y
    println(sum)
  }
}

Досрочная остановка при None

Если любой генератор равен None, весь цикл с вычислением результата возвращает None. Оставшиеся шаги пропускаются.

Это та же досрочная остановка, которую обеспечивает flatMap, но в более удобной для чтения форме.

object Main {
  def main(args: Array[String]): Unit = {
    val a: Option[Int] = Some(3)
    val b: Option[Int] = None
    val sum = for {
      x <- a
      y <- b
    } yield x + y
    println(sum)
  }
}

Как выполняется преобразование

Компилятор преобразует цикл for с вычислением результата в flatMap и map. Эти два фрагмента эквивалентны.

Понимание этого помогает предсказывать тип результата.

object Main {
  def main(args: Array[String]): Unit = {
    val a: Option[Int] = Some(3)
    val b: Option[Int] = Some(4)
    val viaFor = for { x <- a; y <- b } yield x + y
    val viaFlatMap = a.flatMap(x => b.map(y => x + y))
    println(viaFor)
    println(viaFlatMap)
  }
}

Использование предыдущих значений

Последующие генераторы могут ссылаться на значения, связанные ранее. Благодаря этому каждый шаг может зависеть от предыдущего.

object Main {
  def main(args: Array[String]): Unit = {
    val base: Option[Int] = Some(10)
    val result = for {
      x <- base
      y <- Some(x * 2)
    } yield x + y
    println(result)
  }
}

Промежуточные связывания

Внутри цикла с вычислением результата можно вводить обычные значения с помощью = (без стрелки). Это удобно для промежуточных вычислений.

object Main {
  def main(args: Array[String]): Unit = {
    val a: Option[Int] = Some(6)
    val result = for {
      x <- a
      doubled = x * 2
    } yield doubled + 1
    println(result)
  }
}

Условия с if

Цикл с вычислением результата может содержать фильтр if. Если условие не выполняется, результатом становится None.

object Main {
  def main(args: Array[String]): Unit = {
    val a: Option[Int] = Some(8)
    val even = for {
      x <- a
      if x % 2 == 0
    } yield x
    println(even)
    val b: Option[Int] = Some(7)
    println(for { x <- b if x % 2 == 0 } yield x)
  }
}

Объединение поисковых операций

Типичный вариант использования: найти несколько ключей и объединить их, только если все они присутствуют.

object Main {
  val data = Map("a" -> 1, "b" -> 2)
  def main(args: Array[String]): Unit = {
    val combined = for {
      x <- data.get("a")
      y <- data.get("b")
    } yield x + y
    println(combined)
    val missing = for {
      x <- data.get("a")
      z <- data.get("c")
    } yield x + z
    println(missing)
  }
}

Зачем нужны циклы for с вычислением результата?

Они дают Вам:

  • Понятную последовательность зависимых Options
  • Автоматическую досрочную остановку при None
  • Те же возможности, что и flatMap/map, но в более плоской записи
  • Фильтрацию с помощью if и промежуточные связывания с помощью =

Получение обычного значения

Цикл с вычислением результата возвращает Option, поэтому завершите его с помощью getOrElse или fold, чтобы получить обычное значение.

object Main {
  def main(args: Array[String]): Unit = {
    val a: Option[Int] = Some(3)
    val b: Option[Int] = Some(4)
    val total = (for { x <- a; y <- b } yield x + y).getOrElse(0)
    println(total)
  }
}

Собираем всё вместе

Полный конвейер: разобрать два входных значения, проверить условие, объединить результаты и указать значение по умолчанию.

object Main {
  def parse(s: String): Option[Int] = s.toIntOption
  def main(args: Array[String]): Unit = {
    val result = for {
      x <- parse("10")
      y <- parse("5")
      if y != 0
    } yield x / y
    println(result.getOrElse(-1))
  }
}

Быстрая проверка

Проверьте, насколько хорошо Вы поняли циклы for с вычислением результата для Option.

Повторение

Вы научились объединять Options с помощью циклов for с вычислением результата:

  • for { x <- a; y <- b } yield ... наглядно выстраивает Options в последовательность
  • Он преобразуется в flatMap/map
  • Любой None досрочно превращает весь результат в None
  • Последующие генераторы могут использовать предыдущие значения; = добавляет связывания, а if выполняет фильтрацию
  • Завершите конструкцию с помощью getOrElse или fold, чтобы получить обычное значение
Можно начать бесплатно

Изучай Scala с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
39
Уроки
143

Часто задаваемые вопросы

Урок «Option в for-comprehension» бесплатный?

Да — полный текст урока «Option в for-comprehension» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Scala for Backend Engineering & Functional Programming, подпишись на CoddyKit PRO. Курс Scala for Backend Engineering & Functional Programming содержит 4 уроков всего.

Чему я научусь в уроке «Option в for-comprehension»?

Объединяйте варианты в цепочку Ты практикуешь Scala for Backend Engineering & Functional Programming с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Scala for Backend Engineering & Functional Programming?

Предыдущий опыт не требуется. Scala for Backend Engineering & Functional Programming на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Option в for-comprehension»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Scala for Backend Engineering & Functional Programming?

Да. Каждый урок Scala for Backend Engineering & Functional Programming включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Избегаем null
  2. map и flatMap для Option
  3. getOrElse и fold
  4. Option в for-comprehension
← Назад к Scala for Backend Engineering & Functional Programming