假设我有许多akka服务,它们都返回包含在AbcDto
中的Try
类型的案例类。
所以我使用map
调用所有这些服务并返回List[Future[Any]]
。
现在我使用Future.sequence
将其转换为Future[List[Any]]
。
如何打开我的最终结果列表?我想只在所有这些都是Success
的情况下处理它们,即使一个失败我也想抛出错误。
我尝试将Future[List[Any]]
映射为:
val a: List[Future[Any]]
a.map {
case r: List[Success[AbcDto]] => println("hello")
}
但这会给出错误:
case r: List[Try[AbcDto]]
。此时它的给定错误:类型模式scala.util.Try[AbcDto]
中的非变量类型参数List[scala.util.Try[AbcDto]]
(List[scala.util.Try[AbcDto]]
的基础)
答案 0 :(得分:1)
由于所有akka服务都会在Try中返回...
x=y=np.linspace(-0.020,0.020,20)
zz = np.empty((20,20)); zz[:,:] = np.nan
zz[10:,10:] = z
zz[10:,:10] = np.fliplr(z)
zz[:10,:] = np.flipud(zz[10:,:])
...
,因此AbcDto
的正确类型应为val a
。现在,通过List[Future[Try[AbcDto]]]
和flatMap操作的组合可以实现所需的结果,以检查服务中的任何故障,如下所示。
Future.sequence
答案 1 :(得分:1)
Future[A]
和Try[A]
非常相似,我认为没有必要从这些actor中返回Try[A]
。如果成功,您只需返回A
,Future[A]
ask
List
sequence
Future[List[A]]
ask
并akka.actor.Status.Failure
在单个故障的情况下,它将包含第一个遇到的异常。这似乎正是你所要求的。
要将演员的失败告知Throwable
,您应该try-catch
发送Try
的相关实例。
P.S。关于使用object Try {
/** Constructs a `Try` using the by-name parameter. This
* method will ensure any non-fatal exception is caught and a
* `Failure` object is returned.
*/
def apply[T](r: => T): Try[T] =
try Success(r) catch {
case NonFatal(e) => Failure(e)
}
}
使用非惯用Scala的评论。它实际上是。以下是try-catch
创建的实现方式:
devtools
如您所见,它在内部使用devtools::use_vignette()
。如果Scala标准库作者对此很好,那么你也应该如此。 :)
答案 2 :(得分:0)
如果我理解正确(你问题中的类型有点令人困惑),
您从val responseFutures: List[Future[Any]]
开始,转换后您有val responsesFuture: Future[List[Any]]
。流氓的答案是正确的,但它可以使用一些澄清:
您的编译器错误是由Success
不是类,而object
unapply
Try
的提取器引起的。因此,您不能以这种方式使用in类型。
所以像case r: List[Try[AbcDto]] if r.forall(_.isSuccess) => println("hello")
这样的东西应该编译。但是,当AbcDto
被删除时,您将收到有关擦除的编译器警告。因此@unchecked
。
<强>更新强>
类型擦除意味着,编译器无法在编译时检查模式匹配中的类型参数类型。在您的情况下,所有编译都知道您的输入类型是Future[List[Try[Any]]]
。
所以
future.map {
case _: List[Try[AbcDto]] => ???
}
将导致编译器警告,因为编译器只看到。
future.map {
case _: List[Try[_]] => ???
}
@unchecked
注释只会抑制相应的编译器警告。
最后,在上面的模式匹配中,您只需将任何进入Try[AbcDto]
的内容转换为没有任何编译时类型安全性。