简短形式:我有一个与 . 签名相同的方法Future.recover
。将部分函数传递给Future
的版本有效。将相同的 PF 传递给我的版本会导致missing parameter type for expanded function. The argument types of an anonymous function must be fully known. (SLS 8.5)
错误。有什么不同?
更长的形式:我正在尝试实现此处TracingFuture
讨论的类,以尝试跨未来边界跟踪错误。基本技术是将 Future 包装在另一个类中,同时添加一个伪堆栈跟踪。TracingFuture
博客文章中给出的代码缺少recover
from 的方法Future
,所以我用相同的签名添加了它:
class TracingFuture[+T](underlying: Future[T], val trace: Vector[FutureTraceElement]) extends Future[T] {
def recover[U >: T](pf: PartialFunction[Throwable, U]
)(implicit ec: ExecutionContext, enclosing: sourcecode.Enclosing, file: sourcecode.File,
line: sourcecode.Line): TracingFuture[U] = {
val recovered = underlying.recover(pf)
new TracingFuture[U](recovered, trace :+ FutureTraceElement(enclosing.value, "recover", file.value, line.value))
}
}
为了比较,这是Future
. 请注意,除了额外的隐式参数之外,签名是相同的。
trait Future[+T] extends Awaitable[T] {
def recover[U >: T](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Future[U] =
transform { _ recover pf }
}
最后,我产生编译错误的代码:
val x: TracingFuture[Vector[Maintainer]] = ... // code producing a TracingFuture
val fMaintainers = x.recover {
case err: Throwable ⇒
logger.error("Failed to get list of user maintainers.", err)
Vector.empty[Maintainer]
}
和错误信息:
[error] /Users/bwbecker/oat/src/oat3/modules/wapp/app/oat/wapp/dao/CronJobDAO.scala:273: missing parameter type for expanded function
[error] The argument types of an anonymous function must be fully known. (SLS 8.5)
[error] Expected type was: ?
[error] val fMaintainers = x.recover {
[error] ^
再一次,这段代码适用于,Future.recover
但我得到一个编译错误TracingFuture.recover
。我不明白为什么。
这个 SO question解释了编译器知道偏函数的参数必须是 T 的超类型,但不能保证。但是为什么它没有遇到这个问题Future.recover
呢?
而且,当然,我想知道除了重写匿名部分函数以使类型显式之外,我是否还能做些什么。