Created
January 29, 2026 09:02
-
-
Save ddrpa/68df08f9877d5f8a3952bb4d2e3c2468 to your computer and use it in GitHub Desktop.
Type R for Java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package cc.ddrpa.labs.lang; | |
| import java.util.Optional; | |
| import java.util.function.Function; | |
| import java.util.function.Supplier; | |
| public record R<T, E>(T value, E error) { | |
| public static <T, E> R<T, E> ok(T value) { | |
| return new R<>(value, null); | |
| } | |
| public static <T, E> R<T, E> err(E error) { | |
| return new R<>(null, error); | |
| } | |
| /** | |
| * 执行给定的 supplier,并将结果包装为 Result。 | |
| * <p> | |
| * - 如果 supplier 成功返回值,则返回 Result.ok(value)。 | |
| * - 如果 supplier 抛出任何异常 (Throwable),则捕获异常并返回 Result.err(exception)。 | |
| * <p> | |
| * 这允许将可能抛异常的操作转化为安全的 Result,而无需调用方使用 try/catch。 | |
| * <p> | |
| * 示例: | |
| * <pre> | |
| * Result<Integer, Throwable> r1 = R.of(() -> 10 / 2); | |
| * // r1 = Result.ok(5) | |
| * | |
| * Result<Integer, Throwable> r2 = R.of(() -> 10 / 0); | |
| * // r2 = Result.err(ArithmeticException) | |
| * </pre> | |
| * | |
| * @param supplier 可能抛异常并返回 T 的操作 | |
| * @param <T> 成功值类型 | |
| * @return 如果 supplier 成功执行,返回 Result.ok(value);如果抛异常,返回 Result.err(exception) | |
| */ | |
| public static <T> R<T, Throwable> of(Supplier<T> supplier) { | |
| try { | |
| return R.ok(supplier.get()); | |
| } catch (Throwable e) { | |
| return R.err(e); | |
| } | |
| } | |
| public boolean isOk() { | |
| return error == null; | |
| } | |
| public boolean isErr() { | |
| return !isOk(); | |
| } | |
| public Optional<T> valueOpt() { | |
| return Optional.ofNullable(value); | |
| } | |
| public Optional<E> errorOpt() { | |
| return Optional.ofNullable(error); | |
| } | |
| /** | |
| * 将当前 Result 的成功值应用给定函数 f 转换为新的成功值。 | |
| * 如果当前 Result 是失败值,则保持失败不变。 | |
| * <p> | |
| * 这允许你对成功结果进行变换,同时保持失败信息不受影响。 | |
| * <p> | |
| * 示例: | |
| * <pre> | |
| * Result<Integer, String> r1 = Result.ok(10); | |
| * Result<Integer, String> r2 = r1.map(x -> x * 2); | |
| * // r2 = Result.ok(20) | |
| * | |
| * Result<Integer, String> r3 = Result.err("error"); | |
| * Result<Integer, String> r4 = r3.map(x -> x * 2); | |
| * // r4 = Result.err("error"),失败保持不变 | |
| * </pre> | |
| * | |
| * @param f 将成功值 T 转换为新值 U 的函数 | |
| * @param <U> 新成功值类型 | |
| * @return 转换后的 Result,如果当前 Result 失败则保持失败 | |
| */ | |
| public <U> R<U, E> map(Function<T, U> f) { | |
| return isOk() ? R.ok(f.apply(value)) : R.err(error); | |
| } | |
| /** | |
| * 如果当前 Result 表示成功值 (isOk() == true),则将其值传入给定的函数 f, | |
| * 并返回函数的结果。 | |
| * <p> | |
| * 如果当前 Result 表示失败值 (isErr() == true),则直接返回原失败,不会调用函数 f。 | |
| * <p> | |
| * 这允许你将多个可能失败的操作串联起来:每一步都可能返回失败,一旦遇到失败,后续操作不会执行。 | |
| * <p> | |
| * 示例: | |
| * <pre> | |
| * Result<Integer, String> r1 = Result.ok(10); | |
| * Result<Integer, String> r2 = r1.flatMap(x -> Result.ok(x * 2)); | |
| * // r2 = Result.ok(20) | |
| * | |
| * Result<Integer, String> r3 = Result.err("error"); | |
| * Result<Integer, String> r4 = r3.flatMap(x -> Result.ok(x * 2)); | |
| * // r4 = Result.err("error"),lambda 不会执行 | |
| * </pre> | |
| * | |
| * @param f 将成功值 T 转换为另一个 Result<U, E> 的函数 | |
| * @param <U> 新的成功值类型 | |
| * @return 如果当前 Result 成功,返回 f.apply(value) 的结果;如果当前失败,返回原失败 | |
| */ | |
| public <U> R<U, E> flatMap(Function<T, R<U, E>> f) { | |
| return isOk() ? f.apply(value) : R.err(error); | |
| } | |
| /** | |
| * 如果当前 Result 表示失败值 (isErr() == true),则使用给定函数 f 将失败值转换为成功值。 | |
| * 如果当前 Result 已经是成功值,则保持不变。 | |
| * <p> | |
| * 这允许你在失败时提供一个“降级值”或者默认值。 | |
| * <p> | |
| * 示例: | |
| * <pre> | |
| * Result<Integer, String> r1 = Result.err("error"); | |
| * Result<Integer, String> r2 = r1.recover(e -> 0); | |
| * // r2 = Result.ok(0) | |
| * | |
| * Result<Integer, String> r3 = Result.ok(10); | |
| * Result<Integer, String> r4 = r3.recover(e -> 0); | |
| * // r4 = Result.ok(10) ,原成功值保持不变 | |
| * </pre> | |
| * | |
| * @param f 将失败值 E 转换为成功值 T 的函数 | |
| * @return 如果当前 Result 成功,返回自身;如果失败,返回通过 f 转换后的成功 Result | |
| */ | |
| public R<T, E> recover(Function<E, T> f) { | |
| return isOk() ? this : R.ok(f.apply(error)); | |
| } | |
| /** | |
| * 将当前 Result 的失败值应用给定函数 f 转换为新的失败值。 | |
| * 如果当前 Result 是成功值,则保持成功不变。 | |
| * <p> | |
| * 这允许你在传播失败时对错误信息进行调整或包装,而不影响成功结果。 | |
| * <p> | |
| * 示例: | |
| * <pre> | |
| * Result<Integer, String> r1 = Result.err("error"); | |
| * Result<Integer, Integer> r2 = r1.mapError(e -> e.length()); | |
| * // r2 = Result.err(5) | |
| * | |
| * Result<Integer, String> r3 = Result.ok(10); | |
| * Result<Integer, Integer> r4 = r3.mapError(e -> e.length()); | |
| * // r4 = Result.ok(10) ,成功保持不变 | |
| * </pre> | |
| * | |
| * @param f 将失败值 E 转换为新失败值 F 的函数 | |
| * @param <F> 新失败值类型 | |
| * @return 转换后的 Result,如果当前 Result 成功则保持成功 | |
| */ | |
| public <F> R<T, F> mapError(Function<E, F> f) { | |
| return isOk() ? R.ok(value) : R.err(f.apply(error)); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment