【发布时间】:2016-07-21 02:48:33
【问题描述】:
在没有等待完成的情况下就未来调用.toString 会导致不确定的结果。我的问题是为什么在 scala 2.10.x 和 2.11.x 中调用 .toString 未完成的期货返回 "List()"? The implementation 似乎并没有明确说明这一点。
可以从 REPL 中观察到这种行为:
scala> import scala.concurrent.Future, scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.ExecutionContext.Implicits.global
scala> Future(1).toString
res0: scala.concurrent.Future[Int] = Success(1)
scala> Future(1).toString
res1: scala.concurrent.Future[Int] = List()
请注意,Scala 2.12.x 可能会显式实现 Future#toString 以返回 "Future(<not completed>)" (source)。
编辑:证明这不是来自 REPL 的人工制品或“一些隐藏的隐含”(-Yno-predef 删除了所有默认隐含):
Future.scala:
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
object Main extends App {
System.out.println(Future(1).toString)
}
build.sbt:
scalaVersion := "2.11.8"
scalacOptions := Seq(
"-deprecation",
"-encoding", "UTF-8",
"-feature",
"-unchecked",
"-Yno-predef",
"-Xfatal-warnings",
"-Xlint",
"-Yinline-warnings",
"-Yno-adapted-args",
"-Ywarn-dead-code",
"-Ywarn-unused-import",
"-Ywarn-numeric-widen",
"-Ywarn-value-discard",
"-Xfuture")
【问题讨论】:
-
我一直在使用 Scala 2.11.7 获得
scala.concurrent.impl.Promise$DefaultPromise@34a2d6e0 -
在 2.11.8 中,对于未完成的
Future,您确实会得到List()。 -
你很可能有一些隐藏的隐式定义会产生这种行为。
-
这是REPL调试中的一个。尝试将其分配给
val -
@cchantep 我不这么认为,
println(Future(1).toString)也会打印出List(),同样的结果也可以从 REPL 中复制出来。