Poprzednie części:

Dopasowanie wzorców do wartości jest w sumie proste. Podobny efekt można uzyskać stosując mapy. Jednak Javaslang udostępnia też API, w którym dopasowanie oparte jest o predykaty. Przy czym są to predykaty biblioteki, a nie Javy 8.

Listing 1. Dopasowanie z wykorzystaniem predykatu

public void predicates() {
    Integer i = 0;
    String on = Match(i).of(
            Case(x -> x == 1, "Jeden"),
            Case(x -> x == 2, "Dwa"),
            Case($(), "?")
    );
    System.out.println(on);
}

Predykaty z API

Oczywiście API Javaslang udostępnia nam cały zestaw predykatów, których możemy użyć „od ręki”:

Listing 2. Przykładowe predykaty z API

public void predicates2(Object i) {
    String on = Match(i).of(
            Case(is(1), "Jeden"),
            Case(isIn(2, 3), "Dwa albo 3"),
            Case(anyOf(is(4), noneOf(is(5), is(6))), "4 lub nie (5 lub 6)"),
            Case(instanceOf(String.class), "Jakiś napis"),
            Case($(), "?")
    );
    System.out.println(on);
}

Do wyboru, do koloru. Predykaty można łączyć na wiele sposobów. anyOf, noneOf to tylko dwa z kilku dostępnych.

Wartości zwracane

Dotychczas patrzyliśmy tylko na to, jak można zdefiniować dopasowanie. Wartość zwracana z warunku była na sztywno zapisana w kodzie. Zamiast tego można użyć funkcji i Supplierów z API Javy 8:

Listing 3. Przykładowe zwracanie wartości

public void returnig() {
    Integer i = 1;
    String on = Match(i).of(
            Case($(1), v -> v + ""),
            Case($(2), () -> "Dwa"),
            Case($(), "?")
    );
    System.out.println(on);
}

Efektywnie Match zachowuje się jak wyrażenie i musi zwrócić wartość. Co w przypadku gdy zamiast zwracania wartości chcemy wykonać jakąś czynność? W tym przypadku musimy użyć metody pomocniczej run:

Listing 4. Użycie run w celu uruchomienia kodu

public void running() {
    Integer i = 1;
    Void of = Match(i).of(
            Case($(1), x -> run(()->System.out.println(x))),
            Case($(2), x -> run(()->System.out.println(x))),
            Case($(), () -> null)
    );
}

Krytycznym wymaganiem jest opakowanie run w Supplier. W przeciwnym wypadku zostanie on uruchomiony przed procedurą dopasowania. Dlaczego? Ponieważ ewaluacja parametrów w Javie jest zachłanna.

Podsumowanie

Jak widać, dopasowanie wzorców w wersji Javaslang jest dobrze rozwinięte i pozwala na uzyskanie wielu rozwiązań, które są znane z języków, gdzie mechanizm ten jest częścią samego języka.