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

Избегаем null

Основы Option

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

Проблема с null

Во многих языках отсутствующее значение представляют с помощью null. Но null вызывает печально известное исключение NullPointerException, если забыть проверить значение.

Scala предлагает более безопасную альтернативу: тип Option.

Что такое Option

Option[A] представляет значение, которое может присутствовать или отсутствовать. У него ровно два случая:

  • Some(value), когда значение существует
  • None, когда значения нет

Сам тип сообщает, что значение может отсутствовать.

object Main {
  def main(args: Array[String]): Unit = {
    val present: Option[Int] = Some(42)
    val absent: Option[Int] = None
    println(present)
    println(absent)
  }
}

Создание Some

Оберните существующее значение в Some, чтобы указать, что оно точно присутствует.

object Main {
  def main(args: Array[String]): Unit = {
    val name: Option[String] = Some("Ada")
    println(name)
  }
}

Представление отсутствия с помощью None

None — единственное значение, используемое, когда ничего нет. Оно подходит для любого типа Option.

object Main {
  def lookup(found: Boolean): Option[Int] =
    if (found) Some(100) else None
  def main(args: Array[String]): Unit = {
    println(lookup(true))
    println(lookup(false))
  }
}

Функции, которые могут завершиться неудачей

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

object Main {
  def findUser(id: Int): Option[String] =
    if (id == 1) Some("Grace") else None
  def main(args: Array[String]): Unit = {
    println(findUser(1))
    println(findUser(2))
  }
}

Проверка с помощью isDefined и isEmpty

isDefined сообщает, является ли Option значением Some, а isEmpty — является ли оно None.

object Main {
  def main(args: Array[String]): Unit = {
    val a: Option[Int] = Some(5)
    val b: Option[Int] = None
    println(a.isDefined)
    println(b.isEmpty)
  }
}

Сопоставление с образцом для Option

Поскольку Option — это запечатанный ADT, его можно сопоставлять с образцом. Это наглядно обрабатывает как наличие, так и отсутствие значения.

object Main {
  def greet(name: Option[String]): String = name match {
    case Some(n) => s"Hello, $n"
    case None    => "Hello, stranger"
  }
  def main(args: Array[String]): Unit = {
    println(greet(Some("Bo")))
    println(greet(None))
  }
}

Option из допускающих null значений

Если приходится работать с кодом, который возвращает null, оберните его в Option(...). Он преобразует null в None, а любое настоящее значение — в Some.

object Main {
  def main(args: Array[String]): Unit = {
    val maybe = Option("data")
    val nothing = Option(null)
    println(maybe)
    println(nothing)
  }
}

Методы стандартной библиотеки возвращают Option

Многие встроенные методы уже возвращают Option, не допуская ошибок. Например, List.headOption безопасно обрабатывает пустые списки.

object Main {
  def main(args: Array[String]): Unit = {
    val xs = List(1, 2, 3)
    val empty = List.empty[Int]
    println(xs.headOption)
    println(empty.headOption)
  }
}

Почему Option лучше null

Option лучше null, потому что он:

  • Делает отсутствие значения видимым в типе
  • Заставляет вызывающий код обрабатывать случай отсутствия
  • Устраняет NullPointerExceptions
  • Сочетается с map, flatMap и последовательными выражениями for

Объединяем всё вместе

Небольшой поиск, возвращающий Option, который затем безопасно обрабатывается с помощью сопоставления с образцом.

object Main {
  val prices = Map("apple" -> 3, "pear" -> 5)
  def priceOf(item: String): Option[Int] = prices.get(item)
  def main(args: Array[String]): Unit = {
    priceOf("apple") match {
      case Some(p) => println(s"costs $p")
      case None    => println("not for sale")
    }
    println(priceOf("banana"))
  }
}

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

Проверьте, насколько хорошо вы поняли Option.

Итоги

Вы научились избегать null с помощью Option:

  • Option[A] — это Some(value) или None
  • Он явно указывает в типе на возможное отсутствие
  • Проверяйте с помощью isDefined/isEmpty или сопоставления с образцом
  • Используйте Option(x) для оборачивания допускающих null значений
  • Методы библиотеки, такие как headOption и Map.get, возвращают Option

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

Урок «Избегаем null» бесплатный?

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

Чему я научусь в уроке «Избегаем null»?

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

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

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

Сколько времени занимает урок «Избегаем null»?

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