#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