Избегаем 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 — локальная установка не требуется.