Обработка исключений идиоматически с VAVR - PullRequest
1 голос
/ 29 апреля 2020

Выплюнув коул-помощник Google Guava, и погрузившись головой в наше новое увлечение VAVR и его сверкающими идеалами, скажем, мы map() пинг Stream, выполняя foldLeft() на Traversable или аналогичный, и одна из внутренних функций выдает проверенное исключение. Теперь мы смотрим на ошибки компилятора, необработанные исключения.

Как следует обрабатывать такие исключения в идеале с idiomati c VAVR. Как выглядит полученный код, каковы шаблоны. У нас есть Option с и Try с ... Как все это получается вместе.

О, и уловки, подобные хитрым исключениям, нас не интересуют.

1 Ответ

1 голос
/ 29 апреля 2020

Вы можете использовать CheckedFunction[0-8].liftTry() для преобразования функции, которая выбрасывает отмеченные исключения, в общую функцию, которая возвращает результат исходной функции, заключенной в Try. Если исходная функция возвращает значение без выброса, оно будет заключено в Success, если оно выбрасывает, исключение будет заключено в Failure.

Затем вам нужно будет принять решение о том, как обрабатывать ошибки в контексте нескольких значений. Вот несколько примеров того, что вы можете сделать с кучей Try значений.

Array<String> input = Array.of(
        "123", "456", "789", "not a number", "1111", "another non-number"
);

// try and parse all the strings
Array<Try<Integer>> trys = input.map(CheckedFunction1.liftTry(Integer::parseInt));

// you can take just the successful values
Array<Integer> values = trys.flatMap(Try::iterator);

// you can look just for the failures
Array<Throwable> failures = trys.filter(Try::isFailure).map(Try::getCause);

// you can partition by the outcome and extract values/errors
Tuple2<Traversable<Integer>, Traversable<Throwable>> partition =
    trys.partition(Try::isSuccess)
        .map(
            seq -> seq.map(Try::get),
            seq -> seq.map(Try::getCause)
        );

// you can do a short-circuiting parse of the original sequence
// this will stop at the first error and return it as a failure
// or take all success values and wrap them in a Seq wrapped in a Try
Try<Seq<Integer>> shortCircuit = Try.sequence(
    input.iterator() //iterator is lazy, so it's not fully evaluated if not needed
         .map(CheckedFunction1.liftTry(Integer::parseInt))
);
// Failure(java.lang.NumberFormatException: For input string: "not a number")

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

...