我的新工作场所大量使用函数java或者是错误处理(http://www.functionaljava.org/javadoc/4.5/functionaljava/fj/data/Either.html)。
几乎没有使用例外。
由于很多原因,这非常烦人。命名一: 在方法内的每个api调用(返回一个Either)必须首先检查返回的Either是否是错误,然后再继续下一行。如果它是一个错误,它将以一种Either的形式传回方法调用的堆栈中。堆栈中的每个方法都需要检查返回的Either是否有错误,直到最后我们将找到负责处理错误的方法。 这导致结构非常糟糕的java代码。我不能写一个正常的流程java代码,因为我必须"停止"每次api通话(所以流是不可能的)。例如
Either<Error, Value> myMethod(String someVar) {
Either<Error, Value> valEither someService.getSomething(someVar)
if (valEither.isRight()) {
Either<Error, Value> otherValue someService.getSomethingElse(valEither.right().value())
if (otherValue.isRight()) ..... //you get the idea
} else {
//maybe log
return valEither;
}
}
当然,我可以使用Either(我这样做)的monadic方法,但这并不能解决必须要求&#34;问&#34;返回类型,如果它是一个错误或值。 我认为使用Either作为错误处理的基础设施并不是一个好主意(长期分配,长方法,嵌套泛型等)有很多原因。
为了解决这个问题,我想到可能会为每个api调用抛出一个特定的异常,它会返回一个&#34;错误&#34;在我目前正在进行的顶级方法上,捕获异常一次。
Value val = myService.getSomething().rightOrThrow(new MyException("blaa"));
但这似乎不可能作为Either投影类型的唯一方法,它做了类似的事情,抛出一个java错误,这并不意味着(几乎)在任何情况下被捕获(我可以意外地捕获stackoverflow或outofmemory错误。)
myService.getSomething().right().valueE("some error msg");
有任何建议或想法吗?
由于
答案 0 :(得分:1)
当我在FJ编程时,我也暂时遇到了这个问题。我很快意识到使用Exceptions
这种方式并不是很有帮助,而且像Either
这样的更多本机构造在语法上要轻得多,并且当然更适合该语言。
当使用函数方法(例如bimap
和map
等)构建更多功能时,我确实使用了 return someService.getSomething(someVar)
.bimap((e)-> new Error("getSomething died for " + someVar, e),
(x)-> someService.getSomethingElse(x))
.right().map((x)-> someService.getSAnotherThing(x));
,所以类似于:
{{1}}
对于支持模式匹配的语言,也许这个结构似乎更有意义。
关于如何抛出错误,好吧,看看valueE实现,您可以简单地编写自己的静态版本,抛出任何你想要的东西
答案 1 :(得分:0)
我发现抛出异常的最佳解决方案是在返回的Either是错误的情况下:
either.right.on(err -> {throw new MyException(err);})
或使用辅助方法使其更具可读性:
static <A> A willFailWith(String errorMsg) {
throw new MyException(errorMsg);
}
either.right.on(err -> willFailWith(err))