为什么 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,它不适合协方差。 Future
s 不会遇到这个问题,因为您无法像使用 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]
.
在 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,它不适合协方差。 Future
s 不会遇到这个问题,因为您无法像使用 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]
.