在 Cyclops React "Try with Resources" 块中,我想将 an 映射IOException到自定义异常类型。我也用 Javaslang 尝试过这个,但似乎不太灵活,因为它对所有异常都一视同仁。
代码示例:
private static Try<String, ConnectionError> readString() {
    // Socket is a thread-local static field
    final Try<String, IOException> string = Try.catchExceptions(IOException.class)
            .init(() -> new BufferedReader(new InputStreamReader(socket.get().getInputStream())))
            .tryWithResources(BufferedReader::readLine);
    return string.isSuccess() ? Try.success(string.get()) :
            Try.failure(new ConnectionError("Could not read from server", string.failureGet()));
}
这可以以更优雅的方式完成吗?还是没有任何意义,返回会更好Try<String, IOException>?
免责声明:我是使用 Cyclops React 库和一般函数式编程的新手,所以我可能有严重的概念误解。
有一个名为 validate 的方法,它作为输入接受一个实例Option和一个Predicate- 两个参数(是的,我知道Option应该作为参数传递,但这里是简化的现实世界场景。现在,如果Option为空,我需要抛出NotFoundException。当它有一个与Predicate传递的值不匹配的值,它应该失败ForbiddenException。如果它有值并且它匹配谓词,则不会发生任何事情。
所以这将是:
                Option, Predicate
                     /\
          isEmpty() /  \ isDefined()  
                   /    \
            throw NFE    matches(Predicate)
                        / \
                    no /   \ yes 
                      /     \
                throw FE     end
我有一些解决方案,但希望潜在的回答者能够清醒地回答这个问题;) 如果两个测试都失败,我的问题是第一个异常。如果我可以期待任何东西,我期待一个优雅的解决方案;) 允许所有 vavr 生物 ( Either, Validation, Try..)
其中一个想法是使用 double Option:
Option
  .of(o.getOrElseThrow(NotFoundException::new))
  .filter(p)
  .getOrElseThrow(ForbiddenException::new);
但这似乎有点尴尬。
在这里可以找到示例项目。
是否有最简单的方法可以在下面编写此代码而不使用toStream()?
import io.vavr.collection.List;
import io.vavr.control.Option;
import lombok.Value;
public class VavrDemo {
    public static void main(String[] args) {
        Foo bar = new Foo(List.of(new Bar(1), new Bar(2)));
        Number value = Option.some(bar)
                .toStream()              // <- WTF?!?
                .flatMap(Foo::getBars)
                .map(Bar::getValue)
                .sum();
        System.out.println(value);
    }
    @Value
    static class Foo {
        private List<Bar> bars;
    }
    @Value
    static class Bar {
        private int value;
    }
}
我在理解验证库时遇到了一些麻烦io.vavr.control.Validation.有可能提出过于宽泛的问题,我确实有几个子问题 - 但我相信它们是密切相关的,并且会拼凑起来帮助我理解使用这种验证机制的正确方法.
我从这里的例子开始:https://softwaremill.com/javaslang-data-validation.
Validation<String, ValidRegistrationRequest> validate(RegistrationRequest request) {
   return combine(
       validateCardId(request.getCardId()),
       validateTicketType(request.getTicketType()),
       validateGuestId(request.getGuestId())
)
       .ap(ValidRegistrationRequest::new)
       .mapError(this::errorsAsJson);
}
private Validation<String, Card> validateCardId(String cardId) {
    // validate cardId
    // if correct then return an instance of entity the cardId corresponds to
}
private Validation<String, TicketType> validateTicketType(String ticketType) {
    // validate ticketType
    // if known then return enumeration representing the ticket
}
private Validation<String, Guest> validateGuest(String guestId) {
    // validate guestId
    // if correct then return …我正在阅读Vavr使用指南中关于使用Match和其他"语法糖"执行副作用的部分.这是给出的例子:
Match(arg).of(
    Case($(isIn("-h", "--help")), o -> run(this::displayHelp)),
    Case($(isIn("-v", "--version")), o -> run(this::displayVersion)),
    Case($(), o -> run(() -> {
        throw new IllegalArgumentException(arg);
    }))
);
然后讨论如何run不应该在lambda体外运行等等.
恕我直言,在解释中缺少一些东西让我完全清晰,即run在某些Vavr接口(我找不到)上的现有方法,或者它应该是我自己在周围代码库中的方法?
所以我努力并且稍微阐述了上面的例子,我可以运行并看到它的结果:
@Test public void match(){
String arg = "-h";
        Object r = Match(arg).of(
                Case($(isIn("-h", "--help")), o -> run(this::displayHelp)),
                Case($(isIn("-v", "--version")), o -> run(this::displayVersion)),
                Case($(), o -> run(() -> {
                    throw new IllegalArgumentException(arg);
                }))
            );
        System.out.println(r);
    }
    private Void run(Supplier<String> supp) {
        System.out.println(supp.get());
        return null;}
    private String displayHelp() {return "This …我正在尝试Either根据选项值返回值。我的目标是如果该选项存在则返回Either.right(),否则代码应返回Either.left()。我使用 Java 8 和 vavr 0.9.2
我想避免有条件的叠瓦
public Either<String, Integer> doSomething() {
    Optional<Integer> optionalInteger = Optional.of(Integer.MIN_VALUE);
    Option<Integer> integerOption = Option.ofOptional(optionalInteger);
    return integerOption.map(value -> {
      //some other actions here
      return Either.right(value);
    }).orElse(() -> {
      //some other checks her also 
      return Either.left("Error message");
    });
}
编译器失败并显示此消息
Error:(58, 7) java: no suitable method found for orElse(()->Either[...]age"))
    method io.vavr.control.Option.orElse(io.vavr.control.Option<? extends io.vavr.control.Either<java.lang.Object,java.lang.Integer>>) is not applicable
      (argument mismatch; io.vavr.control.Option is not a functional interface
          multiple non-overriding abstract methods found in interface io.vavr.control.Option)
    method io.vavr.control.Option.orElse(java.util.function.Supplier<? …我不是java类型系统和异常处理方面的专家。但我发现我们应该只捕获异常而不是可抛出的异常。
这是链接: Difference Between using Throwable and Exception in a try catch
在 Vavr 的库中我找到了这个源代码:
public interface Try<T> extends Value<T>, Serializable {
    long serialVersionUID = 1L;
    static <T> Try<T> of(CheckedFunction0<? extends T> supplier) {
        Objects.requireNonNull(supplier, "supplier is null");
        try {
            return new Try.Success(supplier.apply());
        } catch (Throwable var2) {
            return new Try.Failure(var2);
        }
    }
}
如果我将来使用这个容器,会有什么问题吗?我会错过执行“of”函数期间可能发生的一些关键异常吗?
在我的项目中,我经常有一个模式,其中我链接了多个可能成功也可能不成功的方法。
我很难找到使用 Vavr 实现它的最干净的方法。除了这两种方法还有其他方法吗?
最好是不需要我创建不必要的 lambda,我什至不使用传递的变量。
   // First way to do it: use flatMap to chain it
    public Try<String> mainMethod(String someParam) {
        return firstOperation()
                .flatMap(v -> secondOperation(someParam))
                .flatMap(v -> thirdOperation(someParam));
    }
   // Second way to do it: pattern matching
    public Try<String> otherMainMethod(String someParam) {
        Try<String> firstResult = firstOperation();
        return Match(firstResult)
                .of(
                        Case(
                                $Success($()),
                                () -> {
                                    Try<String> secondResult = secondOperation(someParam);
                                    return Match(secondResult)
                                            .of(
                                                    Case($Success($()), thirdOperation(someParam)),
                                                    Case($Failure($()), secondResult));
                                }),
                        Case($Failure($()), firstResult));
    }
    private Try<String> firstOperation() {
        return Try.of(
                () -> { …我在阅读Vavr的Lazy源码时遇到过如下代码:
private transient volatile Supplier<? extends T> supplier;
private T value; // will behave as a volatile in reality, because a supplier volatile read will update all fields (see https://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#volatile)
public T get() {
    return (supplier == null) ? value : computeValue();
}
private synchronized T computeValue() {
    final Supplier<? extends T> s = supplier;
    if (s != null) {
        value = s.get();
        supplier = null;
    }
    return value;
}
这是一个著名的模式,称为“双重检查锁定”,但对我来说它看起来很糟糕。假设我们将此代码嵌入到多线程环境中。如果该get()方法由第一个线程调用并且供应商构造了一个新对象,(对我而言)由于以下代码的重新排序,另一个线程有可能看到半构造的对象:
private synchronized T computeValue() { …我想抛出从ExceptionifTry.ofCallable()失败扩展而来的异常。
我有一个类型的可调用:
final Callable<MyResponse> decoratedCallable =
    circuitBreakerService.getDecoratedMethod(
        myArg1, 
        () -> myFunction(myArg1, myArg2, myArg3)
    );
我正在尝试这样的事情:
Try.ofCallable(decoratedCallable).onFailure(throwable -> {
    if (throwable instanceof CallNotPermittedException) {
        throw new MyRuntimeExceptionA("msg1", throwable);
    } else {
        throw new MyRuntimeExceptionB("msg2", throwable);
    }
});
如果两者都有效,则此方法有效(包装上述两个语句的函数会抛出正确的异常 MyRuntimeExceptionA 和 MyRuntimeExceptionB)MyRuntimeExceptionA,但如果它们扩展,则MyRuntimeExceptionB无效。RuntimeExceptionException
如果它们扩展Exception,那么我无法将它们从主函数中抛出。IDE 要求将它们包装在 try/catch 中 - 我不希望这样做。
vavr ×10
java ×9
java-8 ×2
concurrency ×1
currying ×1
either ×1
exception ×1
generics ×1
java-stream ×1
lazy-loading ×1
optional ×1
resilience4j ×1
validation ×1
volatile ×1