我有一个方法,String
作为输入,也应该返回String
。
以下ASCII艺术介绍了逻辑流程:
Option<A> optA = finder.findA(input);
optA
/\
isEmpty() / \ isDefined()
/ \
"ERR_1" Option<B> optB = finder.findB(optA.get().bid);
/ \
isEmpty() / \ isDefined()
/ \
"ERR_2" opt2.get().id
基本上对于给定的input
我正在寻找A
包裹在Option
中的A
对象。然后B
出现我正在寻找Option
- 也包含在ERR_1
中,否则返回B
。然后,如果存在ERR_2
,则返回其ID,否则返回var value = 'asdasd';
var isValid = value.match(/^[a-zA-Z]$/);
if (isValid) {
// valid
} else {
// not valid
}
。
我想知道如何使用选项(或模式匹配可能?)以一种简洁的方式(没有任何 ifology )实现它 - 可能是一行的。
有人可以提出建议吗?
可以找到试用的源代码here。
答案 0 :(得分:5)
看起来你有3个可能的退出点:
您可以通过Javaslang执行此操作:
optA
.map(a -> finder.findB(a.bid)
.map(b -> b.bid)
.getOrElse("ERR_2"))
.getOrElse("ERR_1");
如果optA
为空,我们会直接跳到orElse("ERR_1")
如果optA
不为空,我们正在使用内部存储的值,以便在b.bid
空虚的情况下获取值"ERR_2"
或optB
。
此外,在纯Java 8中,它看起来像这样:
optA
.map(a -> finder.findB(a.bid)
.map(b -> b.bid)
.orElse("ERR_2"))
.orElse("ERR_1");
答案 1 :(得分:4)
由于你正在使用javaslang,Try
似乎是一个更好的选择,因为它在链中传播错误,而Option只传播它的空虚&#34;。
如果您可以更改findA
和findB
以返回Try
,则可获得:
Try<B> b = finder.findA(input)
.flatMap(a -> finder.findB(a.bid))
如果你不能,那么:
Try<B> b = finder.findA(input).toTry(() -> new Exception("ERR_1"))
.flatMap(a -> findB(a.bId).toTry(() -> new Exception("ERR_2")))
这是一个暂定的B
,我不确定您是否要将有效值和错误折叠为相同的值,如果情况如此:
String value = b.getOrElseGet(Throwable::getMessage)
如果您在创建无意义异常时遇到问题,可以在每个查找操作中使用Either
,其中左侧值是您的错误类型。这似乎可以更好地模拟问题,但可能会有较长类型签名的缺点,具体取决于您如何拆分表达式。
答案 2 :(得分:0)
您需要将其改编为您的代码,但这是我使用的方法。
首先,隔离要为每个故障点封装的错误。
match
执行此操作后,您可以稍后编写lambda,以便在需要时提供特定的错误消息。
现在,我们编写选项。
match(v1, unique(v1))
#[1] 1 1 2 3 4 5 6
要提取Supplier<? extends RuntimeException> missingAException = IllegalStateException::new;
Supplier<? extends RuntimeException? missingBException = IllegalStateException::new;
,请使用与Optional<A> optA = finder.find(input);
Optional<B> optB = finder.findB(optA.orElseThrow(missingAException));
相同的模式。
optB