模式匹配匹配所有的 Case 条件
Pattern Matching matches all the Case condition
我是新的 vavr,所以我不知道我是否缺少一些基本的东西,但我正在做 Java 目前没有的模式匹配。调试后,我意识到 vavr 匹配所有案例,但如果案例条件不匹配,则如果提供了供应商,则不会执行该值。是吗?
例如:
public Enum Days{
MONDAY,
TUESDAY...
}
String s = Match(days).of(
Case($(Days.MONDAY), "monday"),
Case($(Days.TUESDAY), "tuesday")
);
在上面的示例中,如果 days = MONDAY,它调用 CASE 方法传递枚举值并检查是否存在匹配项。在这种情况下,它是一个匹配项,因此它将 return "monday"。我希望在我们得到匹配后模式匹配将被终止。但事实证明它在星期二也再次进入 Case 方法,模式不匹配所以值仍然存在 "monday" 但我想知道是否有一种方法可以在满足条件后停止模式匹配。
Vavr Match
将 在第一个匹配处停止 Case
并将 return 关联值。
您遇到的只是标准 Java 行为。参数在传递给方法之前急切地求值,所以,当你写
Case(Pattern, retValExpression)
和 retValExpression
是一个表达式,retValExpression
表达式将被 急切求值 ,甚至在将其传递给 API.Case
工厂方法之前.如果您希望 retValExpression
表达式仅在 Case
匹配时被 lazily 评估,您需要通过创建一个将其转换为 Supplier
lambda 表达式:
Case(Pattern, () -> retValExpression)
在这种情况下,只有当对应的 Case
匹配时,lambda 表达式 () -> retValExpression
才会被计算。
如果您的问题在于 Pattern
表达式急切求值,您可以应用相同的技术通过为 Predicate
:
提供 lambda 将它们转换为延迟求值
Case($(value -> test(value)), () -> retValExpression)
我不同意:只要一个案例匹配,它就会停止评估其他案例,假设您以惰性模式编写案例(例如使用 Predicates 和 Suppliers)。问题来自 Java 默认情况下急于对其参数评估,这与 Vavr 无关。
这是你所声称的反例。请注意:
- 匹配器是惰性的(用 Predicate 写的)
- 这些值是惰性的(与供应商一起编写)
.
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;
}
}
执行时,会产生:
Inside predicate one
Inside result 1
1
请注意,第二个谓词和第二个结果都没有被计算过。
我是新的 vavr,所以我不知道我是否缺少一些基本的东西,但我正在做 Java 目前没有的模式匹配。调试后,我意识到 vavr 匹配所有案例,但如果案例条件不匹配,则如果提供了供应商,则不会执行该值。是吗?
例如:
public Enum Days{
MONDAY,
TUESDAY...
}
String s = Match(days).of(
Case($(Days.MONDAY), "monday"),
Case($(Days.TUESDAY), "tuesday")
);
在上面的示例中,如果 days = MONDAY,它调用 CASE 方法传递枚举值并检查是否存在匹配项。在这种情况下,它是一个匹配项,因此它将 return "monday"。我希望在我们得到匹配后模式匹配将被终止。但事实证明它在星期二也再次进入 Case 方法,模式不匹配所以值仍然存在 "monday" 但我想知道是否有一种方法可以在满足条件后停止模式匹配。
Vavr Match
将 在第一个匹配处停止 Case
并将 return 关联值。
您遇到的只是标准 Java 行为。参数在传递给方法之前急切地求值,所以,当你写
Case(Pattern, retValExpression)
和 retValExpression
是一个表达式,retValExpression
表达式将被 急切求值 ,甚至在将其传递给 API.Case
工厂方法之前.如果您希望 retValExpression
表达式仅在 Case
匹配时被 lazily 评估,您需要通过创建一个将其转换为 Supplier
lambda 表达式:
Case(Pattern, () -> retValExpression)
在这种情况下,只有当对应的 Case
匹配时,lambda 表达式 () -> retValExpression
才会被计算。
如果您的问题在于 Pattern
表达式急切求值,您可以应用相同的技术通过为 Predicate
:
Case($(value -> test(value)), () -> retValExpression)
我不同意:只要一个案例匹配,它就会停止评估其他案例,假设您以惰性模式编写案例(例如使用 Predicates 和 Suppliers)。问题来自 Java 默认情况下急于对其参数评估,这与 Vavr 无关。
这是你所声称的反例。请注意:
- 匹配器是惰性的(用 Predicate 写的)
- 这些值是惰性的(与供应商一起编写)
.
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;
}
}
执行时,会产生:
Inside predicate one
Inside result 1
1
请注意,第二个谓词和第二个结果都没有被计算过。