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

map и flatMap для Option

Безопасно комбинируйте операции

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

Преобразование Option

Часто у вас есть Option, и вы хотите преобразовать значение, если оно присутствует, оставив None без изменений.

Метод map делает именно это, избавляя от необходимости вручную извлекать значение.

Использование map

map применяет функцию к значению внутри Some и возвращает новый Some. Для None он ничего не делает и возвращает None.

object Main {
  def main(args: Array[String]): Unit = {
    val n: Option[Int] = Some(10)
    val doubled = n.map(x => x * 2)
    println(doubled)
  }
}

map для None

Если Option равен None, map полностью пропускает функцию и остаётся равным None.

Это ключевое свойство безопасности: при отсутствии значения преобразования ничего не делают.

object Main {
  def main(args: Array[String]): Unit = {
    val empty: Option[Int] = None
    val result = empty.map(x => x * 2)
    println(result)
  }
}

Изменение типа

map может преобразовать значение в другой тип, как и при работе с коллекциями. Здесь Option[Int] превращается в Option[String].

object Main {
  def main(args: Array[String]): Unit = {
    val n: Option[Int] = Some(7)
    val label = n.map(x => s"value=$x")
    println(label)
  }
}

Проблема вложенности

Что, если ваша функция сама возвращает Option? Использование map даст вложенный тип Option[Option[A]], с которым неудобно работать.

Здесь на помощь приходит flatMap.

object Main {
  def half(x: Int): Option[Int] = if (x % 2 == 0) Some(x / 2) else None
  def main(args: Array[String]): Unit = {
    val n: Option[Int] = Some(8)
    val nested = n.map(half)
    println(nested)
  }
}

Использование flatMap

flatMap применяет функцию, возвращающую Option, и разворачивает результат в один Option.

Сравните этот результат с вложенной версией из предыдущей сцены.

object Main {
  def half(x: Int): Option[Int] = if (x % 2 == 0) Some(x / 2) else None
  def main(args: Array[String]): Unit = {
    val n: Option[Int] = Some(8)
    val flat = n.flatMap(half)
    println(flat)
  }
}

Цепочка вызовов flatMap

Поскольку каждый шаг возвращает Option, можно объединить в цепочку несколько вызовов flatMap. Если на каком-либо шаге получается None, вся цепочка становится равной None.

object Main {
  def half(x: Int): Option[Int] = if (x % 2 == 0) Some(x / 2) else None
  def main(args: Array[String]): Unit = {
    val result = Some(16).flatMap(half).flatMap(half)
    println(result)
  }
}

Прерывание цепочки на None

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

Такое автоматическое прерывание избавляет от ручных проверок null.

object Main {
  def half(x: Int): Option[Int] = if (x % 2 == 0) Some(x / 2) else None
  def main(args: Array[String]): Unit = {
    val result = Some(8).flatMap(half).flatMap(half)
    println(result)
  }
}

Сочетание map и flatMap

Используйте flatMap для шагов, возвращающих Option, а map — для последнего обычного преобразования.

object Main {
  def parse(s: String): Option[Int] = s.toIntOption
  def main(args: Array[String]): Unit = {
    val result = Some("21").flatMap(parse).map(_ * 2)
    println(result)
  }
}

Почему map и flatMap?

Эти методы позволяют:

  • Преобразовывать значения, не извлекая их из контейнера
  • Автоматически пропускать действия для None
  • Объединять в цепочку операции, которые могут завершиться ошибкой
  • Избегать вложенного Option[Option[A]] с помощью flatten

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

Реалистичная цепочка: найти ключ, разобрать его, а затем преобразовать — и всё это безопасно.

object Main {
  val config = Map("port" -> "8080")
  def main(args: Array[String]): Unit = {
    val port = config.get("port").flatMap(_.toIntOption).map(_ + 1)
    println(port)
    val missing = config.get("host").flatMap(_.toIntOption)
    println(missing)
  }
}

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

Проверьте, насколько хорошо Вы поняли работу map и flatMap.

Повторение

Вы научились объединять Options в цепочку:

  • map преобразует значение внутри Some, оставляя None без изменений
  • flatMap применяет функцию, возвращающую Option, и разворачивает результат
  • Цепочка досрочно останавливается и возвращает None, если на каком-либо шаге получен None
  • Используйте flatMap для шагов, возвращающих Option, а map — для обычных шагов

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

Урок «map и flatMap для Option» бесплатный?

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

Чему я научусь в уроке «map и flatMap для Option»?

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

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

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

Сколько времени занимает урок «map и flatMap для Option»?

Большинство уроков 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