在 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()));
}
Run Code Online (Sandbox Code Playgroud)
这可以以更优雅的方式完成吗?还是没有任何意义,返回会更好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
Run Code Online (Sandbox Code Playgroud)
我有一些解决方案,但希望潜在的回答者能够清醒地回答这个问题;) 如果两个测试都失败,我的问题是第一个异常。如果我可以期待任何东西,我期待一个优雅的解决方案;) 允许所有 vavr 生物 ( Either
, Validation
, Try
..)
其中一个想法是使用 double Option
:
Option
.of(o.getOrElseThrow(NotFoundException::new))
.filter(p)
.getOrElseThrow(ForbiddenException::new);
Run Code Online (Sandbox Code Playgroud)
但这似乎有点尴尬。
在这里可以找到示例项目。
是否有最简单的方法可以在下面编写此代码而不使用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;
}
}
Run Code Online (Sandbox Code Playgroud) 我在理解验证库时遇到了一些麻烦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 …
Run Code Online (Sandbox Code Playgroud) 我正在阅读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 Code Online (Sandbox Code Playgroud)
然后讨论如何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 …
Run Code Online (Sandbox Code Playgroud) 我正在尝试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");
});
}
Run Code Online (Sandbox Code Playgroud)
编译器失败并显示此消息
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<? …
Run Code Online (Sandbox Code Playgroud) 我不是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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果我将来使用这个容器,会有什么问题吗?我会错过执行“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(
() -> { …
Run Code Online (Sandbox Code Playgroud) 我在阅读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)
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
这是一个著名的模式,称为“双重检查锁定”,但对我来说它看起来很糟糕。假设我们将此代码嵌入到多线程环境中。如果该get()
方法由第一个线程调用并且供应商构造了一个新对象,(对我而言)由于以下代码的重新排序,另一个线程有可能看到半构造的对象:
private synchronized T computeValue() { …
Run Code Online (Sandbox Code Playgroud) 我想抛出从Exception
ifTry.ofCallable()
失败扩展而来的异常。
我有一个类型的可调用:
final Callable<MyResponse> decoratedCallable =
circuitBreakerService.getDecoratedMethod(
myArg1,
() -> myFunction(myArg1, myArg2, myArg3)
);
Run Code Online (Sandbox Code Playgroud)
我正在尝试这样的事情:
Try.ofCallable(decoratedCallable).onFailure(throwable -> {
if (throwable instanceof CallNotPermittedException) {
throw new MyRuntimeExceptionA("msg1", throwable);
} else {
throw new MyRuntimeExceptionB("msg2", throwable);
}
});
Run Code Online (Sandbox Code Playgroud)
如果两者都有效,则此方法有效(包装上述两个语句的函数会抛出正确的异常 MyRuntimeExceptionA 和 MyRuntimeExceptionB)MyRuntimeExceptionA
,但如果它们扩展,则MyRuntimeExceptionB
无效。RuntimeException
Exception
如果它们扩展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