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

Either для ошибок

Left и Right

«Either для ошибок» — бесплатный урок 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 уроков всего.

Зачем нужен Either?

Either представляет значение, которое может быть одним из двух вариантов. Это идиоматичный способ моделировать вычисления, которые могут завершиться ошибкой с информацией о ней.

  • Left обычно содержит ошибку.
  • Right обычно содержит успешный результат.

В отличие от Option, который сообщает лишь, что что-то отсутствует, Either сообщает, что именно пошло не так.

Тип Either

Either[A, B] — это запечатанный признак с двумя подтипами: Left[A] и Right[B].

Запомнить можно так: Right — это правильно, а Left содержит ошибку. Благодаря этому соглашению map и flatMap автоматически работают со стороной успешного результата.

val ok: Either[String, Int] = Right(42)
val err: Either[String, Int] = Left("boom")
println(ok)
println(err)

Возврат Either из функции

Функция, которая может завершиться ошибкой, возвращает Either, а не выбрасывает исключение. Затем вызывающий код может явно обработать оба результата.

object Main {
  def parseAge(s: String): Either[String, Int] =
    s.toIntOption match {
      case Some(n) if n >= 0 => Right(n)
      case Some(_)          => Left("age cannot be negative")
      case None             => Left("not a number")
    }

  def main(args: Array[String]): Unit = {
    println(parseAge("30"))
    println(parseAge("-5"))
    println(parseAge("x"))
  }
}

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

Самый прямой способ использовать Either — сопоставление с образцом. Обработайте Left и Right отдельно.

@main def run(): Unit = {
  val result: Either[String, Int] = Right(10)
  val msg = result match {
    case Right(value) => s"Got value: $value"
    case Left(error)  => s"Failed: $error"
  }
  println(msg)
}

fold: объединение обеих сторон

fold принимает две функции: одну для Left и одну для Right, — и возвращает единый результат общего типа.

Это краткая альтернатива сопоставлению с образцом, когда Вам нужно получить значение.

@main def run(): Unit = {
  val r: Either[String, Int] = Right(7)
  val label = r.fold(
    err => s"error: $err",
    num => s"double is ${num * 2}"
  )
  println(label)
}

map работает со стороной Right

map преобразует значение Right, оставляя Left без изменений. Так проявляется смещение Either вправо в Scala (начиная с версии 2.12).

@main def run(): Unit = {
  val ok: Either[String, Int]  = Right(5)
  val no: Either[String, Int]  = Left("missing")
  println(ok.map(_ + 1))
  println(no.map(_ + 1))
}

getOrElse и значения по умолчанию

getOrElse извлекает значение Right или возвращает запасное значение, если Either содержит Left.

@main def run(): Unit = {
  val ok: Either[String, Int] = Right(99)
  val no: Either[String, Int] = Left("oops")
  println(ok.getOrElse(0))
  println(no.getOrElse(0))
}

swap: смена сторон

swap меняет местами Left и Right. Это удобно, когда нужно работать со стороной ошибки с помощью методов, ориентированных вправо.

@main def run(): Unit = {
  val err: Either[String, Int] = Left("bad input")
  val swapped = err.swap.map(_.toUpperCase)
  println(swapped)
}

isLeft и isRight

Быстрые логические проверки позволяют выполнить ветвление без полного сопоставления с образцом.

  • isRight возвращает true для успешного результата.
  • isLeft возвращает true для ошибки.
@main def run(): Unit = {
  val r: Either[String, Int] = Right(1)
  println(r.isRight)
  println(r.isLeft)
}

toOption: отбросить ошибку

Когда причина сбоя больше не важна, toOption преобразует Either в Option: Right(x) становится Some(x), а Left(_) — None.

@main def run(): Unit = {
  val ok: Either[String, Int] = Right(3)
  val no: Either[String, Int] = Left("err")
  println(ok.toOption)
  println(no.toOption)
}

Пример проверки

Соберём всё вместе: проверим имя пользователя, возвращая типизированную ошибку при сбое.

object Main {
  def validate(name: String): Either[String, String] =
    if (name.isEmpty) Left("empty name")
    else if (name.length > 10) Left("name too long")
    else Right(name)

  def main(args: Array[String]): Unit = {
    println(validate("alice"))
    println(validate(""))
    println(validate("verylongusername"))
  }
}

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

Проверьте, насколько хорошо Вы понимаете соглашения, используемые в Either.

Итоги

Вы научились моделировать ошибки с помощью Either:

  • Right = успех, Left = ошибка (с ориентацией вправо).
  • Обрабатывайте их с помощью сопоставления с образцом или fold.
  • Преобразуйте успешный результат с помощью map, задавайте значения по умолчанию с помощью getOrElse.
  • Меняйте стороны с помощью swap, преобразуйте значение с помощью toOption.

Далее Вы научитесь обрабатывать исключения с помощью Try.

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

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

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

Чему я научусь в уроке «Either для ошибок»?

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

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

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

Сколько времени занимает урок «Either для ошибок»?

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

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

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

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

  1. Either для ошибок
  2. Try, Success, Failure
  3. Композиция Either
  4. Преобразование между типами
← Назад к Scala for Backend Engineering & Functional Programming