模式匹配
常用import
1 2 3 4
| import static io.vavr.API.$; import static io.vavr.API.Case; import static io.vavr.API.Match; import static io.vavr.Patterns.$Tuple2;
|
简单匹配
1 2 3 4 5 6 7 8
| var name = 1;
String greetMsg = Match(name).of( Case($(1), "yes"), Case($(), "no") );
assertEquals("yes", greetMsg);
|
匹配Tuple
1 2 3 4 5 6 7 8 9
| var t = Tuple.of(1, "joy");
String greetMsg = Match(t).of( Case($Tuple2($(1), $()), (a, b) -> "hello " + b), Case($(e -> e._1 == 1), "123"), Case($(), "unknown") );
assertEquals("hello joy", greetMsg);
|
匹配Try
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import static io.vavr.API.Try; import static io.vavr.Patterns.$Failure; import static io.vavr.Patterns.$Success;
var s = Try(() -> 1);
String r = Match(s).of( Case($Success($()), "success"), Case($Failure($()), "failure"), Case($(), "failure") );
assertEquals("success", r);
var f = Try(() -> 1 / 0);
String r2 = Match(f).of( Case($Success($()), "success"), Case($Failure($(e -> RuntimeException.class.isAssignableFrom(e.getClass()))), "runtime exception"), Case($Failure($()), "failure"), Case($(), "unknown") );
assertEquals("runtime exception", r2);
|
对自定义类型进行匹配
1 2 3 4 5 6 7 8
| var p = new Person(1, "joy");
String greetMsg = Match(p).of( Case(Person.$id(1), (id, name) -> "hello " + name), Case($(), () -> "unknown") );
assertEquals("hello joy", greetMsg);
|
其中Person如下
1 2 3 4 5 6 7 8 9
| @AllArgsConstructor public static class Person { Integer id; String name;
public static Match.Pattern2<Person, Integer, String> $id(Integer id) { return Match.Pattern2.of(Person.class, $(id), $(), _p -> Tuple.of(_p.id, _p.name)); } }
|
一点优化
match的of参数每次需创建n个Case,可使用Supplier优化效率,如下代码
1 2 3 4 5 6 7 8 9 10 11 12
| @SafeVarargs public static <T, R> R match(T value, Supplier<Match.Case<? extends T, ? extends R>> ...cases) { Objects.requireNonNull(cases, "cases is null"); for (var _case : cases) { @SuppressWarnings("unchecked") var __case = (Match.Case<T, R>) _case.get(); if (__case.isDefinedAt(value)) { return __case.apply(value); } } throw new IllegalStateException(); }
|
使用方式,增加() ->即可,一个小优化
1 2 3 4 5 6 7 8
| var p = new Person(1, "joy");
String greetMsg = match(p, () -> Case(Person.$id(1), (id, name) -> "hello " + name), () -> Case($(), "unknown") );
assertEquals("hello joy", greetMsg);
|
Either
left代表失败,right代表成功
1 2 3 4 5 6 7 8 9
| Object success = Either.right("value") .right() .getOrElse("defaultValue"); assertEquals("value", success);
Object fail = Either.left("error") .right() .getOrElse("defaultValue"); assertEquals("defaultValue", fail);
|