簡體   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