Option в for-comprehension
Объединяйте варианты в цепочку
«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 — локальная установка не требуется.
Все уроки этого курса
- Избегаем null
- map и flatMap для Option
- getOrElse и fold
- Option в for-comprehension