Побочные эффекты при Вавре

Я просматриваю раздел Руководство по использованию Vavr о выполнении побочных эффектов с Match и другими «синтаксический сахар», как они его называют. Вот пример, приведенный там:

Match(arg).of(
    Case($(isIn("-h", "--help")), o -> run(this::displayHelp)),
    Case($(isIn("-v", "--version")), o -> run(this::displayVersion)),
    Case($(), o -> run(() -> {
        throw new IllegalArgumentException(arg);
    }))
);

а затем обсуждается, как run не следует запускать вне тела лямбда и т. д.

ИМХО, чего-то не хватало в объяснении, чтобы дать мне полную ясность, то есть run существующий метод в каком-то интерфейсе Vavr (который я не смог найти) или это должен быть мой собственный метод в окружающей базе кода?

Поэтому я постарался и немного изложил приведенный выше пример, чтобы я мог запустить его и увидеть результаты:

@Test public void match(){

String arg = "-h";

        Object r = Match(arg).of(
                Case($(isIn("-h", "--help")), o -> run(this::displayHelp)),
                Case($(isIn("-v", "--version")), o -> run(this::displayVersion)),
                Case($(), o -> run(() -> {
                    throw new IllegalArgumentException(arg);
                }))
            );

        System.out.println(r);
    }

    private Void run(Supplier<String> supp) {
        System.out.println(supp.get());
        return null;}

    private String displayHelp() {return "This is a help message.";}
    private String displayVersion() {return "This is a version message.";}

Не мог бы кто-нибудь подтвердить, что я на правильном пути в том, как это было задумано дизайнерами Vavr, или я полностью ушел по касательной, и в этом случае я был бы признателен за некоторые рекомендации относительно того, как это должно быть.

Заранее спасибо.

Обновлено:

import static io.vavr.API.run;

    @Test public void match1() {

            String arg = "-h";

            Object r = Match(arg).of(
                    Case($(isIn("-h", "--help")), o -> run(this::displayHelp)),
                    Case($(isIn("-v", "--version")), o -> run(this::displayVersion)),
                    Case($(), o -> run(() -> {
                        throw new IllegalArgumentException(arg);
                    }))
                );

            System.out.println("match: " +r);
        }

        //private Void run(Supplier<Void> supp) {supp.get();}

        private void displayHelp() {System.out.println("This is a help message.");}
        private void displayVersion() {System.out.println("This is a version message.");}

person Simeon Leyzerzon    schedule 06.02.2018    source источник
comment
Не уверен, какую IDE вы используете, но в случае, если это Eclipse, вы можете настроить автозавершение кода для автоматического импорта через Настройки - ›Java / Editor / Content Assist / Favorites -› Новый тип ... - ›io.vavr.API   -  person Nándor Előd Fekete    schedule 06.02.2018
comment
Да, я использую Eclipse, спасибо.   -  person Simeon Leyzerzon    schedule 06.02.2018
comment
Возможно, документацию можно было бы улучшить, указав import static io.vavr.API.run; - иначе это неочевидно (и неявно напоминает Runnable).   -  person Simeon Leyzerzon    schedule 06.02.2018


Ответы (1)


Это io.vavr.API.run. Согласно Javadoc, вы должны импортировать базовую функциональность VAVR через

import static io.vavr.API.*;

Функция run вызывает Runnable (функцию () -> void) один раз и возвращает (Void)null. Он используется, потому что

Case($(isIn("-h", "--help")), o -> this.displayHelp())

не работает, если displayHelp() равно void, поскольку void не является типом с хорошим поведением в Java. В частности, Supplier<void> и Function<?, void> не работают. Кроме того,

Case($(isIn("-h", "--help")), this.displayHelp())

выполнит displayHelp() перед сопоставлением, поэтому сопоставление бесполезно. Это исключает все три (без учета номера аргумента) перегрузки Case. run исправляет это, потому что Supplier<Void> и Function<?, Void> возможны, а принятие Runnable означает, что действие может быть отложено до тех пор, пока не потребуется аргумент для Case.

person HTNW    schedule 06.02.2018
comment
Итак, если я правильно вас понимаю, вы предлагаете то, что мое первоначальное представление является излишним, поскольку я повторно реализовал существующий io.Vavr.API.run() , и вместо этого код должен быть чем-то вроде метода match1() (см. Обновление вопроса)? А методы создания побочных эффектов предназначены исключительно для побочных эффектов, возврата от них не ожидается? - person Simeon Leyzerzon; 06.02.2018
comment
Ваш новый код правильный, но нет причин не возвращать значение. Если нет возвращаемого значения (что нежелательно, поскольку подразумевает побочные эффекты) run используется, чтобы обойти нарушения Java. Если есть возвращаемое значение (что желательно и является обычным случаем), просто не используйте run. - person HTNW; 06.02.2018