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