Подтвердить что ты не робот

Получить значение параметра или выбросить исключение

Если задан параметр, какой идиоматический способ получить его значение или попробовать исключение?

def foo() : String = {
  val x : Option[String] = ...
  x.getOrException()
}
4b9b3361

Ответ 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