我正在try 探索在Java应用程序中使用Vavr库.我正在try 使用Vavr库的Match.of()构造减少if-else阶梯.

下面是我编写的一段代码:

Match(Option.of(clientId)).of(
                Case($None(), run(() -> {
                    metricsService.recordValidationStageMetrics(CLIENT_ID_NOT_PRESENT, type, BLANK);
                    log.error("Client ID not present in the request header: [{}]", clientId);
                    throw new ValidationException(EX_REQUEST_CLIENT_ID_EMPTY);
                })),
                Case($Some($(StringUtils::isBlank)), run(() -> {
                    metricsService.recordValidationStageMetrics(CLIENT_ID_NOT_PRESENT, type, BLANK);
                    log.error("Client ID not present in the request header: [{}]", clientId);
                    throw new ValidationException(EX_REQUEST_CLIENT_ID_EMPTY);
                })),
                Case($(), run(() -> {
                    if (isClientIdNotAllowed(clientId)) {
                        log.error(LOG_CLIENT_ID_NOT_ALLOWED, clientId);
                        metricsService.recordValidationStageMetrics(CLIENT_ID_NOT_ALLOWED, type, clientId);
                        throw new ValidationException(EX_ALLOWED_CLIENT_ID_ERROR);
                    }
                }))
        );

这里的问题是Option始终与第一条Case语句匹配.即使clientId为非null,也会验证为None并引发异常.

So the question is:

  1. 为什么它的行为不符合预期?我在这里错过了什么?
  2. 有没有更干净的方法来写这个?

推荐答案

实际上,就我所记得的,你需要在run前面加() ->,这表示Case的第二个参数的Supplier变体被使用.否则,将Eager 地对其进行判断,因此将运行第一个Case.

以下代码工作正常:

package lol;

import static io.vavr.API.$;
import static io.vavr.API.Case;
import static io.vavr.API.Match;
import static io.vavr.API.run;
import static io.vavr.Patterns.$None;
import static io.vavr.Patterns.$Some;

import io.vavr.control.Option;

public class Lol {

  public static void main(String[] args) {
    String val = "lol";
    Match(Option.of(val)).of(
        Case($None(), () -> run(() -> {
          System.out.println(1);
          throw new IllegalArgumentException("null");
        })),
        Case($Some($(String::isEmpty)), () -> run(() -> {
          System.out.println(2);
          throw new IllegalArgumentException("empty");
        })),
        Case($(), () -> run(() -> {
          System.out.println(3);
          if ("lol".equals(val)) {
            throw new IllegalArgumentException("lol");
          }
        }))
    )
    ;
  }
}

try 删除() ->,无论输入是什么,都将开始匹配第一个Case.

我是否能写得更干净.这取决于您使用的java版本.如果使用最新的语句,我将其视为switch语句或模式匹配.

Java相关问答推荐

如果它最终将被转换为int类型,为什么我们在Java中需要较小的integer类型?

将状态栏和导航栏设置为白色,带有深色文本

获取拦截器内部的IP地址

在Java中测试DAO方法:假实现与内存数据库

inteliJ中是否有一个功能可以自动在块注释中的/*后面添加一个空格?''

滚动视图&不能在alert 对话框中工作(&Q;&Q;)

内存中的H2修剪尾随空格

Com.google.firebase.database.DatabaseException:无法将类型为java.lang.Boolean的值转换为字符串.这是关于什么的?

如何让JVM在SIGSEGV崩溃后快速退出?

如何在一行中使用Dijkstra中的Java Stream

在Java 15应用程序中运行Java脚本和Python代码

如何在Java中为thunk创建映射器函数

如何在列表(链表)中插入一个新 node (作为prelast)

如何根据配置动态创建N个bean

在线程Java中调用Interrupt()之后调用Join()

Java Flux中的延迟增加

Java KeyListener不工作或被添加

如何在Spring Security中设置一个任何人都可以打开的主页?

如何在Spring Boot中为不同的部署环境管理多个.properties文件?

当我try 返回可选时,Mock无法正常工作