Try
обычно используется для покрытия частей, которые могут вызвать ошибку, например, в случае использования некоторых библиотек Java, которые могут вызвать исключение. Но, если вы хотите вернуть возможную ошибку и заставить клиента ее обработать, Either[A, B]
- гораздо лучший вариант, по крайней мере, потому что вы можете указать более точный тип ошибки для Left[A]
и безопасно сопоставить шаблон с вашим типом A
вместо возможного некорректного сопоставления с некоторыми Throwable
, как вы бы сделали для Failure(t)
.
Итак, в вашем случае возможное решение будет выглядеть так:
sealed trait CalculationError
case class Error1(cause: String) extends CalculationError
def calculate(input: Option[Double]): Either[CalculationError, String] =
input match {
case (Some(value)) => Right(value.toString)
case (None) => Left(Error1("No value found"))
}
}
val result = calculate(....)
result match {
case Right(i) => println(i)
case Left(Error1(s)) => println(s)
}
Это это более безопасный подход, потому что вы можете позже добавить другой тип ошибки, скажем, case class Error2(cause: String) extends CalculationError
, и в части кода, соответствующей шаблону клиента, компиляция покажет предупреждающее сообщение о том, что вы пропустили обработку новой ошибки: Match is not exhaustive
. В случае Failure(t)
компиляция не сможет предложить такое предупреждение, так что на стороне обработки ошибок легче ошибиться.
Надеюсь, это поможет!