如何在Java中使用Vavr进行元组中已定义类型的Option模式匹配

huangapple go评论72阅读模式
英文:

How to pattern match a tuple of Option with defined type in Java with Vavr

问题

new Vavr用户在这里
我正在尝试对一对选项进行模式匹配以便在两者都为Some时执行语句在Scala中我会这样做

    val maybeThis: Option[String] = ???
    val maybeThat: Option[String] = ???

    (maybeThis, maybeThat) match {
      case (Some(dis), Some(that)) => ???
      case _ => ???
    }

在Java中我正在尝试这种方法

    Tuple2<Option<String>, Option<String>> tuple = new Tuple2<>(Option.of(...), Option.of(...));

    return Match(tuple).of(
      Case($Tuple2($Some($(instanceOf(String.class))), $Some($(instanceOf(String.class)))),
                        (someThis, someThat) -> methodWhichEatsTwoStrings(someThis.get(), someThat.get())),
      Case($(), t -> run(() -> {
                    throw new NullPointerException(...);
                })));

然而通过这种实现编译器抱怨它期望得到`Some<Object>`而不是`Some<String>`,如果我在模式中省略`$(instanceOf(String.class)`,则会发生相同的错误

我相当确定这只是一个正确语法的问题但我在努力寻找正确的文档
我错在哪里
谢谢
英文:

new Vavr user here.
I am trying to pattern match a tuple of options to execute a statements if both of them are Some, in Scala I would have done this with:

val maybeThis: Option[String] = ???
val maybeThat: Option[String] = ???

(maybeThis, maybeThat) match {
  case (Some(dis), Some(that)) =&gt; ???
  case _ =&gt; ???
}

In Java, I am trying this approach:

Tuple2&lt;Option&lt;String&gt;, Option&lt;String&gt;&gt; tuple = new Tuple2&lt;&gt;(Option.of(...), Option.of(...));

return Match(tuple).of(
  Case($Tuple2($Some($(instanceOf(String.class))), $Some($(instanceOf(String.class)))),
                    (someThis, someThat) -&gt; methodWhichEatsTwoStrings(someThis.get(), someThat.get())),
  Case($(), t -&gt; run(() -&gt; {
                throw new NullPointerException(...);
            })));

However, with this implementation the compiler complains that it was expecting Some&lt;Object&gt; instead of Some&lt;String&gt;, same error happens if I omit the $(instanceOf(String.class) in the pattern.

I am moderately sure this is merely a problem of proper syntax, yet I am struggling to find the correct documentation.
Where am I wrong?
Thanks

答案1

得分: 1

有一个名为“for comprehension”的vavr API构造,试图在Java中尽可能地模仿Scala的for comprehensions。通过该构造,您可以相当优雅地解决问题。有关更多详细信息,请参阅处理两个Options的For重载。以下是一个示例代码片段:

String methodWhichEatsTwoStrings(String v1, String v2) {
    return v1 + v2; //以某种方式组合这两个值
}

...

Option<String> option1 = Option.some("value1");
Option<String> option2 = Option.some("value2");

String combined = For(option1, option2)
    .yield((v1, v2) -> methodWhichEatsTwoStrings(v1, v2))
    .getOrElseThrow(() -> new NullPointerException("reasons"));

当然,您可以使用Option来包装不同类型的值用于option1option2,或者组合多个选项,而不仅仅是两个。您还可以为yield函数的返回值使用不同的类型。我在所有地方都使用了String,以简化示例并符合您的原始示例。

我想补充一下,我会尽量避免在一个或两个选项为空的情况下抛出NullPointerException。也许可以尝试使用另一个vavr数据类型,比如Either,来表示这种错误情况?

英文:

There's a vavr API construct called for comprehension that tries to mimic Scala's for comprehensions to the extent that it's possible to do in Java. With that construct you could solve your problem quite elegantly. See the For overload for handling two Options for more details. Here's an example code snippet:

String methodWhichEatsTwoStrings(String v1, String v2) {
    return v1 + v2; //combine the two values in some way
}

...

Option&lt;String&gt; option1 = Option.some(&quot;value1&quot;);
Option&lt;String&gt; option2 = Option.some(&quot;value2&quot;);

String combined = For(option1, option2)
    .yield((v1, v2) -&gt; methodWhichEatsTwoStrings(v1, v2))
    .getOrElseThrow(() -&gt; new NullPointerException(&quot;reasons&quot;));

Of course, you could use Option wrapping values of different types for option1 and option2, or combine multiple options, not just two. You could also use a different type for the return value of the yield function as well. I used String everywhere for the sake of simplicity and to conform to your original example.

I would like to add that I would try to avoid throwing NullPointerException in case one or both of the options are empty. Maybe try to use another vavr data type like Either to represent such an error case?

huangapple
  • 本文由 发表于 2020年9月3日 17:22:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/63720606.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定