- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
假设我有这个方法:
public CompletionStage<SomeClass> getData() {
CompletableFuture<SomeClass> future = new CompletableFuture<>();
return CompletableFuture.runAsync(() -> {
// Fetch data from some source
// Then either
// future.complete(data);
// or fail
// future.completeExceptionally(e);
});
return future;
}
现在我想要一个方法,调用 getData
,进行操作,但随后返回 CompletionStage<Either<ErrorResponse, Data>>
public CompletionStage<Either<ErrorResponse, Data>> modifyData() {
return getData()
.thenCompose(d -> CompletableFuture.completedFuture(Either.right(d)))
.exceptionally(e -> Either.left(ErrorResponse.create(e)));
}
当我这样做时, exceptionally
内的类型丢失了,编译器认为我正在返回类型 Either<Object, Data>
.
如果我将该代码更改为:
public CompletionStage<Either<ErrorResponse, Data>> modifyData() {
CompletableFuture<Either<ErrorResponse, Data>> future = new CompetableFuture<>();
CompletableFuture.runAsync(() -> {
getData()
.thenCompose(d -> future.complete(Either.right(d)));
.exceptionally(e ->
future.complete(Either.left(ErrorResponse.create(e)))
});
return future;
}
然后就可以正常工作了。为什么类型丢失了?
最佳答案
你有
public CompletionStage<Either<ErrorResponse, Data>> modifyData() {
return getData()
.thenCompose(d -> CompletableFuture.completedFuture(Either.right(d)))
.exceptionally(e -> Either.left(ErrorResponse.create(e)));
}
thenCompose
是一个泛型方法,但您没有为 Java 提供足够的类型信息来推断您需要其类型参数 U
绑定(bind)到Either<ErrorResponse, Data>
。调用exceptionally
(即使它是通用的)也无法将类型信息反馈给 thenCompose
的调用.
目前,它推断 Object
对于 Either
的第一个类型参数。所以thenCompose
返回 CompletionStage<Either<Object, Data>>
。这会传播到 exceptionally
。自 CompletionStage<Either<Object, Data>>
不是CompletionStage<Either<ErrorResponse, Data>>
,它的返回值类型无效。
您可以通过提供显式类型参数来添加必要的类型信息。
public CompletionStage<Either<ErrorResponse, Data>> modifyData() {
return getData()
.<Either<ErrorResponse, Data>>thenCompose(d -> CompletableFuture.completedFuture(Either.right(d)))
.exceptionally(e -> Either.left(ErrorResponse.create(e)));
}
或更接近有问题的调用
public CompletionStage<Either<ErrorResponse, Data>> modifyData() {
return getData()
.thenCompose(d -> CompletableFuture.completedFuture(Either.<ErrorResponse, Data>right(d)))
.exceptionally(e -> Either.left(ErrorResponse.create(e)));
}
现在 Java 不必尝试和猜测。它知道你的意思。
或者,我会使用 CompletableFuture#handle
处理异常情况。
return getData()
.handle((d, e) -> {
if (e == null) {
return Either.right(d);
}
return Either.left(ErrorResponse.create(e));
});
}
类型信息是独立的。剩下的主要是意见问题。
关于Java CompletionStage 到 CompletionStage<Either> 类型丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45221337/
有没有办法以更“单子(monad)”的方式编写这个函数,而不是在 Either 上使用模式匹配? {-# LANGUAGE LambdaCase #-} calculate :: (Monad m)
我正在使用 cats ,想知道怎么用它转一个数据。 从 val data = Either[Error, Option[Either[Error, Account]]] 到 val target: E
我是 Haskell 的初学者,我正在编写一些使用 Either 的 Haskell 代码用于错误处理。 Either 的左侧元素表示错误,而右侧元素表示成功的结果。代码经常使用 Either 的 A
我有一个 Either 列表,表示错误: type ErrorType = List[String] type FailFast[A] = Either[ErrorType, A] import ca
假设我在 processOne 中有一个 monadic 函数,定义如下: def processOne(输入:输入):Either[ErrorType, Output] = ... 给定“Input
db.findUser(id).then(R.pipe( R.ifElse(firstTestHere, Either.Right, () => Either.Left(err)), R.ma
函数的名称是否定义如下: f :: [Either a b] -> Either [a] [b] f x = let (y1, y2) = partitionEithers x in case y
我尝试通过自己的练习找到解决方案,并满足以下要求: 我们需要根据给定的序列移动对象。 序列由 Action 组成。 以下是可能的操作:F、L、R F:前进 L : 向左旋转 90° R : 向右旋转
给定一个序列 Seq[Either[String,A]],其中 Left 是错误消息。我想获得一个 Either[String,Seq[A]] ,其中我得到一个 Right (这将是一个 Seq[A]
假设我有两个功能: b2c :: B -> Either String C a2bs :: A -> [[B]] 如何使用 b2c 和 a2bs 创建以下 a2cs 函数,以便 [[ 中是否有任何 L
查看 Haskell 的 Either Monad,有一个 >>= 函数。 Prelude Map> let add100 = \x -> Right (x+100 :: Int) Prelude M
我正在使用 cats ,想知道如何用它来转数据: val data = NonEmptyList[Either[Error, User]] 到 val target: Either[Error, No
我正在尝试将 Codable 与协议(protocol)一起使用来处理 API 请求和响应。我正在查询的 API 以“结果”键下的一组项目作为响应: { results: ["id": "1", "i
我有一个 Future[Either[A, B]]以及提供 Future[C] 的函数来自 B . 我需要转换 Future[Either[A, B]]至 Future[Either[A, C]] .
首先,我运行了以下代码,运行良好: class Monster: def __init__(self): self._can_do = [] print("cr
var newRight; if(either.isRight()) { newRight = either.getOrElse(() => throw UnimplementedError())
说我有一些代码: def foo(s:String):Either[Bar, Baz] = // some code here ... 我想将其用作: val a = Array("a", "b",
我的表单有四个字段。我需要: - 如果至少填充一个字段,则验证成功 - 对所有字段使用相同的错误“请输入电话或电子邮件” 下面的代码不能在偶然的基础上工作 - 所有字段都是单独验证的,即使我使用该函数
forall m。 MonadFail m => m 可以替换为 Either String,方法是替换 pure = Right 和 fail = Left。但是,由于 Either String
我试过这个: type TestT = Either Int Float testM :: (a -> a) -> TestT -> TestT testM f (Left x) = Left (f
我是一名优秀的程序员,十分优秀!