Как сопоставить по шаблону кортеж параметра с определенным типом в Java с помощью Vavr

#java #pattern-matching #vavr

#java #сопоставление по шаблону #vavr

Вопрос:

здесь новый пользователь Vavr. Я пытаюсь сопоставить шаблон с кортежем опций для выполнения операторов, если оба они являются некоторыми, в 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) в шаблоне.

Я умеренно уверен, что это просто проблема правильного синтаксиса, но я изо всех сил пытаюсь найти правильную документацию. Где я ошибаюсь? Спасибо

Ответ №1:

Существует конструкция API vavr, называемая for comprehension, которая пытается имитировать Scala для понимания в той степени, в какой это возможно сделать в Java. С помощью этой конструкции вы могли бы решить свою проблему довольно элегантно. Более подробную информацию см. в Для перегрузки для обработки двух опций. Вот пример фрагмента кода:

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

...

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 перенос значений разных типов для option1 и option2 или комбинировать несколько опций, а не только две. Вы также могли бы использовать другой тип для возвращаемого значения yield функции. Я использовал String везде для простоты и в соответствии с вашим исходным примером.

Я хотел бы добавить, что я бы постарался избежать выбрасывания NullPointerException в случае, если один или оба параметра пусты. Может быть, попробовать использовать другой тип данных vavr, такой как Either , для представления такого случая ошибки?