为什么 Promise 不能是协变的

Why can't a Promise be covariant

在 Scala 中,Future 被定义为协变的,而 Promise 是不变的。据说 Promise 几乎可以是逆变的 (https://issues.scala-lang.org/browse/SI-7467)。为什么会这样?

如果 promise 是协变的,你可以这样做:

val p: Promise[Any] = Promise[String]()
p.success(1)

从而用 Int 完成 Promise[String],这将是不安全的。

A Promise 是一个可变的 API,它不适合协方差。 Futures 不会遇到这个问题,因为您无法像使用 Promise 那样手动完成它们。

假设我们有:

class Animal
class Cat extends Animal
class Dog extends Animal

如果您希望 Promise[A]A 上协变,这意味着我们需要 Promise[Cat] <: Promise[Animal]Promise[Dog] <: Promise[Animal]。假设我们可以做到这一点。

好的,假设我们有一个 Promise[Cat]:

val p: Promise[Cat] = ...

根据我们的假设,它也是一个 Promise[Animal]:

val q: Promise[Animal] = p

Promise 有一个名为 complete 的方法,它接受一个 Try[T],它也是协变的。这意味着 Try[Dog] 也是 Try[Animal]。看到这是领先的地方了吗?

我们可以打电话给:

val value: Try[Dog] = ...

q.complete(value)

这是合法的,因为我们试图用 Try[Animal] 完成 Promise[Animal],但是 oops,我们也只是尝试完成一个 Promise[Cat] 和一个 Promise[Dog].