繁体   English   中英

如何使用optionals实现这个嵌套流?

[英]How to implement this nested flow with optionals?

我有一个方法,它将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存在则返回它的id,否则返回ERR_2

我想知道如何使用选项(或模式匹配可能?)以一种简洁的方式(没有任何ifology )实现 - 可能是单行。

有人可以建议吗?

可以在这里找到试用的源代码。

看起来您有3个可能的退出点:

  1. optA empty - >“ERR_1”
  2. optA不为空&& optB为空 - >“ERR_2”
  3. 两者都不为空 - > optB.get()。bid

你可以通过使用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");

因为你正在使用javaslang,所以Try似乎是一个更好的选择,因为它通过链传播错误,而Option只传播它的“空虚”。

如果你可以改变findAfindB返回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 ,其中左侧值是您的错误类型。 这似乎可以更好地模拟问题,但可能会有较长类型签名的缺点,具体取决于您如何拆分表达式。

您需要将其调整为您的代码,但这是我使用的方法。

首先,隔离要为每个故障点封装的错误。

Supplier<? extends RuntimeException> missingAException = IllegalStateException::new;
Supplier<? extends RuntimeException? missingBException = IllegalStateException::new;

这样做允许您稍后编写lambda以提供特定的错误消息,如果您愿意的话。

现在,我们编写选项。

Optional<A> optA = finder.find(input);
Optional<B> optB = finder.findB(optA.orElseThrow(missingAException));

为了提取optB ,因为我们没有使用相同的模式optA

B value = optB.orElseThrow(missingBException);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM