使用 VAVR 惯用地处理异常
Handling exceptions idiomatically with VAVR
把 Google Guava kool-aid 从我们嘴里吐出来,然后一头扎进我们对 VAVR 及其闪闪发光的理想的新迷恋中,假设我们正在 map()
ping Stream
,在 Traversable
上执行 foldLeft()
,或类似的,并且其中一个内部函数抛出检查异常。现在我们正盯着编译器错误、未处理的异常。
如何使用惯用的 VAVR 理想地处理此类异常。结果代码是什么样的,模式是什么。我们有 Option
s 和 Try
s...它们是如何组合在一起的。
哦,我们对偷偷摸摸的异常等技巧不感兴趣。
您可以使用 CheckedFunction[0-8].liftTry()
将抛出已检查异常的函数转换为 returns 将原始函数的结果包裹在 Try
中的总函数。如果原函数returns一个值没有抛出,它会被包裹在一个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
。
把 Google Guava kool-aid 从我们嘴里吐出来,然后一头扎进我们对 VAVR 及其闪闪发光的理想的新迷恋中,假设我们正在 map()
ping Stream
,在 Traversable
上执行 foldLeft()
,或类似的,并且其中一个内部函数抛出检查异常。现在我们正盯着编译器错误、未处理的异常。
如何使用惯用的 VAVR 理想地处理此类异常。结果代码是什么样的,模式是什么。我们有 Option
s 和 Try
s...它们是如何组合在一起的。
哦,我们对偷偷摸摸的异常等技巧不感兴趣。
您可以使用 CheckedFunction[0-8].liftTry()
将抛出已检查异常的函数转换为 returns 将原始函数的结果包裹在 Try
中的总函数。如果原函数returns一个值没有抛出,它会被包裹在一个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
。