为什么Promise不能协变

时间:2017-03-13 16:19:16

标签: scala types promise future covariance

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

2 个答案:

答案 0 :(得分:7)

如果承诺是协变的,你可以做到:

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

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

答案 1 :(得分:1)

Promise是一个可变的API,它在协方差方面表现不佳。 Future不会遇到此问题,因为您无法像使用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)

哪个是合法的,因为我们正在尝试使用Promise[Animal]完成Try[Animal],但 oops ,我们也只是尝试完成{{ 1}}与Promise[Cat]