Сопоставление с образцом соответствует всем условиям дела - PullRequest
1 голос
/ 02 мая 2019

Я новый vavr, поэтому я не знаю, упускаю ли я какие-то базовые вещи, но я делаю сопоставление с образцом, которого у Java сейчас нет.После отладки я понял, что vavr соответствует всем делам, но не будет выполнять значение, если указан поставщик, если условие случая не совпадает.Это верно?

, например:

public Enum Days{
    MONDAY,
    TUESDAY...
}

String s = Match(days).of(
        Case($(Days.MONDAY), "monday"),
        Case($(Days.TUESDAY), "tuesday")
);

В приведенном выше примере, если days = MONDAY, он вызывает метод CASE, передает значение enum и проверяет, есть ли совпадение.В этом случае это совпадение, поэтому он вернет «понедельник».Я надеялся, что сопоставление с образцом будет прекращено, так как мы получили совпадение.Но оказывается, что он снова входит в метод Case для TuESDAY, шаблон не совпадает, поэтому значение остается «понедельником», но мне было интересно, есть ли способ остановить сопоставление с шаблоном после выполнения условия.

Ответы [ 2 ]

3 голосов
/ 02 мая 2019

Vavr Match остановится на первом совпадении Case и вернет соответствующее значение.

То, что вы испытываете, - это просто стандартное поведение Java.Аргументы с нетерпением оцениваются перед передачей в метод, поэтому, когда вы пишете

Case(Pattern, retValExpression)

и retValExpression является выражением, выражение retValExpression будет с нетерпением оценено до того, как дажепередавая его фабричному методу API.Case.Если вы хотите, чтобы выражение retValExpression было лениво , вычисляемое только при совпадении Case, вам необходимо преобразовать его в Supplier, создав лямбда-выражение:

Case(Pattern, () -> retValExpression)

В этом случае лямбда-выражение () -> retValExpression будет оцениваться только при совпадении соответствующего Case.

Если ваша проблема заключается в том, что выражения Pattern получают с нетерпением, вы можете применить то же самоеТехника для преобразования их в ленивую оценку, предоставляя лямбду для Predicate:

Case($(value -> test(value)), () -> retValExpression)
1 голос
/ 03 мая 2019

Я не согласен: как только дело совпадает, оно перестает оценивать другие дела, если вы пишете свои дела в ленивом режиме (например, с Предикатами и Поставщиками).Проблема заключается в том, что Java по умолчанию стремится к оценке аргументов, это не имеет никакого отношения к Vavr.

Вот контрпример к тому, что вы заявляете.Обратите внимание:

  • ленивцы (записаны с предикатом)
  • значения ленивы (написано с поставщиком)

.

public class Main {
  public static void main(String[] args) {
    var result = Match("foo").of(
        Case($(choice("one")), () -> result("1")),
        Case($(choice("two")), () -> result("2"))
    );

    System.out.println(result);
  }

  static Predicate<String> choice(String choice) {
    return string -> {
      System.out.println("Inside predicate " + choice);
      return true;
    };
  }

  static String result(String result) {
    System.out.println("Inside result " + result);
    return result;
  }
}

При выполнении это дает:

Внутренний предикат один

Внутренний результат 1

1

Обратите вниманиечто ни второй предикат, ни второй результат никогда не оценивались.

...