В Scala существует ли уже существующая библиотечная функция для преобразования исключений в параметры?

#scala #scala-option

#scala #scala-option

Вопрос:

Это в основном для того, чтобы обернуть фабричные методы Java, которые генерируют исключения, если элемент не может быть создан на основе входных данных. Я ищу что-то в базовой библиотеке, например:

  def exceptionToOption[A](f: => A):Option[A] ={
    try{
      Some(f)}
    catch{
      case e:Exception => None}
  }
  

Использование:

 val id:Option[UUID] = exceptionToOption(UUID.fromString("this will produce None"))
  

Я знаю, что могу написать свой собственный, но я хочу проверить, что я не изобретаю колесо заново.

Комментарии:

1. должно быть, я упускаю какой-то вариант использования, но не могли бы вы либо использовать?

2. Either мне тоже кажется лучшей идеей. В исключении может быть полезная информация

3. Проверка Scalaz является улучшением по сравнению с любым из этих сценариев.

Ответ №1:

Используйте scala.util.control.Исключение:

 import scala.util.control.Exception._

allCatch opt f
  

И вы можете сделать это более сложным. Например, для перехвата только арифметических исключений и извлечения исключения:

 scala> catching(classOf[ArithmeticException]) either (2 / 0)
res5: Either[Throwable,Int] = Left(java.lang.ArithmeticException: / by zero)
  

Ответ №2:

Да, вы можете взглянуть на scala.util.control.Exception объект. Особенно allCatch функция.

Ответ №3:

Начиная с scala 2.10, вы можете запускать свой код (например, фабричный метод) в scala.util.Попробуйте, а затем преобразуйте его с помощью toOption :

 import scala.util.Try
Try("foo".toInt).toOption  // None
Try("7".toInt).toOption    // Some(7)
  

Или переведено в ваш оригинальный пример:

 val id: Option[UUID] = Try(UUID.fromString("this will produce None")).toOption
  

Ответ №4:

Scalaz обеспечивает проверку [ E, A], которая аналогична Either .

 val result: Validation[Throwable, Something] = ...

result match {
  case Success(x) => ...
  case Failure(x) => ...
}
  

Ответ №5:

Я использую шаблон, основанный на сигнальных и несигнальных NANS на современных компьютерах. NaN означает не-число. Деление на ноль (fp) создает NaN. SNAN генерируют исключения, в результате просто предоставляются NAN без сигнализации, любое будущее вычисление результата также генерирует NAN. Evaluate сигнализирует, TryEvaluate не сигнализирует.

Здесь Ctx=Context[I, R] — это контекстный блок, который содержит входные данные функции [I], результат [R] и исключение. Все это опции. Метод обновления в контексте — это копирование-обновление. Не изменяющее обновление. Super-trait просто оценивает одну или несколько функций, передавая обновленный контекст следующей функции. Основная функция оценки возвращает контекст, если удерживается исключение (пропуская оценку). Context[I, R] имеет функцию, которая преобразует a (I=> R) в a (Context[I,R]=> Context[I,R]). Таким образом, обычная функция может быть легко преобразована в контекстную функцию.

Как вы можете видеть, кода не так много. Функции находятся только в моем пакете утилит и могут использоваться потребителем практически без кода. Использование библиотеки увеличивает накладные расходы на выполняемую работу.

Я использую это для всех своих анализаторов. Анализаторы на основе X-Path просто вызывают последовательность вспомогательных анализаторов. Отсюда и метод evaluate(Seq). Примечание: мне не нравятся методы. Я склонен использовать функции там, где могу.

Упс, кажется, в прошлый раз я публиковал мусор. Вот ссылка на github. https://github.com/tyohDeveloper/acme/tree/master/src/acme/util