在没有未来的情况下获得Scala承诺的结果

时间:2015-04-07 00:41:37

标签: scala

有没有办法直接从成功的承诺中获取价值? 是否真的有必要将future连接到承诺,为此?

scala> import scala.concurrent._
import scala.concurrent._

scala> val result = Promise[Int]
result: scala.concurrent.Promise[Int] = scala.concurrent.impl.Promise$DefaultPromise@2b5fa85f

scala> result success 3
res0: result.type = scala.concurrent.impl.Promise$DefaultPromise@2b5fa85f

scala> result
res1: scala.concurrent.Promise[Int] = scala.concurrent.impl.Promise$DefaultPromise@2b5fa85f

scala> result.isCompleted
res4: Boolean = true

scala> result.value
<console>:12: error: value value is not a member of scala.concurrent.Promise[Int]
              result.value
                     ^

scala> result.future.value.get.get
res6: Int = 3

我正在考虑使用承诺进行线程安全&#34;分配一次&#34;语义。在scala.concurrent源中,promise对象看起来很精简,据我所知它是线程安全的。但是,我宁愿避免添加另一个对象(未来)。我无法找到承诺的成功价值的吸气剂。

2 个答案:

答案 0 :(得分:9)

TL;医生

p.future == p

所以不要担心额外的分配。


讨论

PromiseFuture是免费的。前者表示计算的写(一次)侧,而后者是读侧。

因此,为了从Promise中读取值,您始终需要通过Future来完成。

另一方面,值得注意的是,尽管采用抽象设计,但实现效率很高,PromiseFuture不是单独的实体。以下是future

Promise的实现
private[concurrent] trait Promise[T] extends scala.concurrent.Promise[T] with scala.concurrent.Future[T] {
  def future: this.type = this
}

因此,您可以看到p.futurep实际上相同,而且只是获得了不同的语义。

最重要的是,您可以从承诺访问future,并且您不会在实例分配方面支付任何额外费用。

此外,如果您愿意,可以使语法更好

scala> implicit class DirectAccessPromise[A](val p: Promise[A]) extends AnyVal {
     |   def get = p.future.value.get.get
     | }
defined class DirectAccessPromise

scala> val p = Promise.successful(42)
res0: scala.concurrent.Promise[Int] = scala.concurrent.impl.Promise$KeptPromise@5e8c92f4

scala> p.get
res1: Int = 42

请注意,由于包装器是一个值类,因此您不会支付任何额外的实例化价格

答案 1 :(得分:4)

DefaultPromise返回本身作为未来,因此您无需进行额外分配。即使你是这样,线程安全的成本可能会更高。