在Scala中,Future被定义为协变的,而Promise是不变的。据说一个Promise几乎可以被定义为反变的(https://issues.scala-lang.org/browse/SI-7467)。为什么会这样呢?
如果承诺是协变的,您可以执行以下操作:
val p: Promise[Any] = Promise[String]()
p.success(1)
因此,使用一个不安全的方法,可以完成将Int
转化为Promise[String]
的过程。
一个 Promise
是一个可变的 API,它在协变方面表现不佳。Future
不会遇到这个问题,因为你不能像使用 Promise
一样手动完成它们。
假设我们有:
class Animal
class Cat extends Animal
class Dog extends Animal
如果你希望Promise[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]
,但是糟糕,我们还尝试使用Promise[Dog]
完成一个Promise[Cat]
。Promise
可以被制作成逆变。 - ZhekaKozlov