#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
, для представления такого случая ошибки?