Pattern matching w Javie z Javaslang II
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.