Неожиданный тип возврата vavr либо в reactor

#java #spring-webflux #project-reactor #vavr

#java #spring-webflux #проект-реактор #vavr

Вопрос:

Есть два простых метода, использующих vavr’s Either.

 public Either<String, Integer> testEither(int s) {
    if (s == 0)
        return Either.left("Wrong");
    return Either.right(s);
}

public Mono<Either<String, Integer>> testReactorEither(int s) {
    return Mono.just(s).filter(x -> x == 0).map(Either::right)
            .switchIfEmpty(Mono.just(Either.left("ERROR")));
}
  

Интернет testEither работает нормально, но между тем, testReactorEither возникает ошибка компиляции из «несовместимых типов», которая говорит о предоставленных тип возврата reactor.core.publisher.Mono<io.vavr.control.Either<java.lang.Object,java.lang.Integer>> несовместим с требуемой доходности reactor.core.publisher.Mono<io.vavr.control.Either<java.lang.String,java.lang.Integer>> .

Боюсь, проблема заключается только в том, что метод map(Either::right) просто определяет Right тип Integer , но не выполняет Left тип, и тогда возвращаемый тип метода является Either<?, Integer> . Тогда вопрос в том, как я могу получить ожидаемый возвращаемый тип в этом случае?

[ОБНОВЛЕНО]

Как упоминал Хинс в своем комментарии, проблема связана с ограничением вывода типов Java, и некоторые ссылки, которые я нашел для решения проблемы, перечислены следующим образом:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=511252

https://e.printstacktrace.blog/java-type-inference-generic-methods-chain-call/

https://openjdk.java.net/jeps/101

Комментарии:

1. Если вы заметили в ошибке, что вы передаете объект в сравнении с желаемым значением строки, убедитесь, что вы передаете правильные значения

2. @beastlyCoder Я передал строку "ERROR" слева от любого из них. Строковый объект на самом деле является объектом, и целочисленный объект также является.

Ответ №1:

Второй пример, похоже, «теряет» информацию о типе для левой стороны при map(Either::right) применении.

Добавление некоторого типа ‘hints’ к вызову метода map должно сработать. Таким образом, testreactor либо будет выглядеть следующим образом:

 public Mono<Either<String, Integer>> testReactorEither(int s) {
    return Mono.just(s)
            .filter(x -> x == 0)
            .<Either<String, Integer>>map(Either::right)
            .switchIfEmpty(Mono.just(Either.left("ERROR")));
}
  

Комментарии:

1. Большое спасибо, и это работает. Однако, при сравнении с testEither методом, компилятор также не знает тип Right при возврате Either.left("Wrong") , но вывод типа в данном случае работает идеально. Означает ли это, что в reactor есть проблемы с выводом типов?

2. Я не эксперт в теме вывода типов. Я не думаю, что это зависит от reactor. Я предполагаю, что это связано с тем фактом, что вывод типа должен иметь дело с двумя «уровнями» вывода типа. Таким образом, вывод типа имел бы аналогичную проблему, если бы Either был заключен, например, в Vavr Optional вместо Mono .

3. Большое спасибо за вашу подсказку, и кажется, что дело действительно в ограничении вывода типа java. Я добавил несколько (полезных) ссылок в вопрос.