Java Vavr如何固定Either左侧类型定义Result<T>简化方法签名
实现方案
Vavr 的 Either 是封闭抽象类型,本身不允许自定义子类直接继承,不需要强行继承 Either,通过包装 Either<Error, T> 的方式实现 Result<T>,即可保留 Either 的全部流式操作能力,也不需要额外编写冗余业务逻辑实现。
示例代码
1. 定义 Result 类
import io.vavr.Tuple; import io.vavr.Tuple2; import io.vavr.control.Either; import java.util.function.Function; import java.util.function.Supplier; public final class Result<T> { private final Either<Error, T> delegate; // 私有构造方法,禁止外部直接实例化 private Result(Either<Error, T> delegate) { this.delegate = delegate; } // 工厂方法:构造成功的Result public static <T> Result<T> ok(T value) { return new Result<>(Either.right(value)); } // 工厂方法:构造失败的Result public static <T> Result<T> err(Error error) { return new Result<>(Either.left(error)); } // 代理Either的核心流式方法,保持和Either一致的使用体验 public <U> Result<U> map(Function<? super T, ? extends U> mapper) { return new Result<>(delegate.map(mapper)); } public <U> Result<U> flatMap(Function<? super T, ? extends Result<? extends U>> mapper) { return new Result<>(delegate.flatMap(val -> mapper.apply(val).delegate)); } public T orElse(T fallback) { return delegate.getOrElse(fallback); } public T orElseGet(Supplier<? extends T> supplier) { return delegate.getOrElseGet(supplier); } public <E extends Throwable> T orElseThrow(Function<? super Error, E> exceptionMapper) throws E { return delegate.getOrElseThrow(exceptionMapper); } public boolean isOk() { return delegate.isRight(); } public boolean isErr() { return delegate.isLeft(); } public Error getErr() { return delegate.getLeft(); } public T get() { return delegate.get(); } // 适配流处理的fold方法 public <U> U fold(Function<Error, U> errMapper, Function<T, U> okMapper) { return delegate.fold(errMapper, okMapper); } // 可按需暴露原生Either做扩展操作 public Either<Error, T> toEither() { return delegate; } }
2. 业务方法使用示例
直接实现你需要的简化方法签名:
// 不需要每次重复写Either<Error, xxx> public Result<Employee> processEmployee(Employee e) { if (e.getId() == null) { return Result.err(new Error("员工ID不能为空")); } // 业务处理逻辑 return Result.ok(e); }
3. 流处理调用示例
完全保留Vavr的链式调用能力,写法和原生Either一致,语义更清晰:
List<Employee> employees = ...; List<Tuple2<Employee, String>> processedResults = employees.stream() .map(this::processEmployee) .map(result -> result.fold( err -> Tuple.of(null, err.getMessage()), ok -> Tuple.of(ok, "处理成功") )) .toList();
方案说明
Vavr 的 Either 设计为 sealed 类型,仅允许内部的 Left 和 Right 两个实现类继承,外部自定义子类会直接编译报错,上述包装代理是最轻量化的实现方案,所有核心逻辑都代理给内部的 Either 实例,完全满足简化签名和流式调用的需求。
内容的提问来源于stack exchange,提问作者jakstack
相关产品推荐
相关产品推荐

