Why does `Future#toString` returns `“List()”`?

2019-04-08 00:15发布

问题:

Calling .toString on a future without waiting for complession leads to nondeterministic results. My question is why calling .toString on uncompleted futures returns "List()" in scala 2.10.x and 2.11.x? The implementation does not seem to be explicit about that.

This behavior can be observed from the 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()

Note that Scala 2.12.x will likely explicitly implement Future#toString to return "Future(<not completed>)" instead (source).


Edit: evidence that this is not an artefact comming from the REPL or "some hidden implicit" (-Yno-predef removes all the default implicits):

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")

回答1:

It was an unfortunate side effect of removing the dependence of sun.misc.Unsafe. It is corrected in Scala 2.12 and newer versions of Scala 2.11 IIRC.



标签: scala future