Получить значение параметра или выбросить исключение
Если задан параметр, какой идиоматический способ получить его значение или попробовать исключение?
def foo() : String = {
val x : Option[String] = ...
x.getOrException()
}
Ответы
Ответ 1
(EDIT: это не лучший или самый идиоматический способ сделать это. Я написал его, когда я не был знаком с Scala. Я оставляю его здесь для примера того, как это не делать. как @TravisBrown)
Я думаю, что это действительно сводится к двум вещам:
- Насколько уверен, что это значение есть?
- как вы хотите отреагировать, если это не так?
Если в этот момент вашего кода вы ожидаете значение, которое должно быть там, и в удаленном случае, если вы не хотите, чтобы ваша программа сбой быстро, то я бы сделал только обычный get
и Scala сбросил NoSuchElementException
, если не было значения:
def foo() : String = {
val x : Option[String] = ...
x.get
}
Если вы хотите обрабатывать случай по-другому (выкиньте собственное исключение), я думаю, что более элегантный способ будет выглядеть следующим образом:
def foo(): String = {
val x: Option[String] = None
x match {
case Some(value) => value
case None => throw new MyRuntimeException("blah")
}
}
И, конечно, если вы хотите предоставить свое собственное альтернативное значение для случая, когда Option
является None
, вы просто используете getOrElse
:
def foo(): String = {
val x: Option[String] = None
x.getOrElse("my alternative value")
}
Ответ 2
A throw
"statement" на самом деле является выражением в Scala, и он имеет тип Nothing
, который является подтипом любого другого типа. Это означает, что вы можете просто использовать простой старый getOrElse
:
def myGet[A](oa: Option[A]) = oa.getOrElse(throw new RuntimeException("Can't."))
Вы действительно, действительно, не должны этого делать.
Ответ 3
Просто используйте метод .get.
def get[T](o:Option[T]) = o.get
Он выдает исключение NoSuchElementException, если o является экземпляром None.
В принципе, я бы работал с такими вариантами:
def addPrint(oi:Option[Int]) = oi.map(_+1).foreach(println)
addPrint(Some(41))
addPrint(Some(1336))
addPrint(None)
чтобы избежать вашего конкретного вопроса.
Ответ 4
Я думаю, что это поможет вам оставаться на стороне "Функционального":)
TL; DR
- Throw
Exception
, чтобы сигнализировать о неожиданном сбое в чисто функциональном коде.
- Используйте
Option
для возврата необязательных значений.
- Используйте
Option(possiblyNull)
, чтобы избежать экземпляров Some(null)
.
- Используйте
Either
для сообщения о ожидаемом отказе.
- Используйте
Try
вместо Either
для возврата исключений.
- Используйте
Try
, а не блок catch для обработки непредвиденных сбоев.
- Используйте
Try
при работе с Future
.
- Экспонирование
Try
в публичном API имеет аналогичный эффект как проверенное исключение. Вместо этого используйте вместо этого исключения.
О Either
и Try