[英]Scala Future return Type
I have the following lines of code...我有以下几行代码...
val a = Future { Thread.sleep(10*1000); 42 }
val b = a.map(_ * 2)
After sometime when I check the value of b, I have the following getting printed.一段时间后,当我检查 b 的值时,我打印了以下内容。
scala.concurrent.Future[Int] = Future(Success(84))
Above, b's type is Future[Int];上面,b的类型是Future[Int]; but in the documentation, it says Future's apply method always returns Future(Try[T]).但在文档中,它说 Future 的 apply 方法总是返回 Future(Try[T])。 The documentation and the above example contradict.文档和上面的例子是矛盾的。 Can someone please help.有人可以帮忙吗。
Please post your imports and the documentation you have referenced.请发布您的导入和您引用的文档。
I think best parallel to understanding this is:我认为与理解这一点最相似的是:
Try[T]
is like Option[T]
, Try[T]
is always Success[T](value: T)
or Failure[T](exception: Throwable)
, just like Option[T]
is always Some[T](value: T)
or None
Try[T]
就像Option[T]
, Try[T]
总是Success[T](value: T)
或Failure[T](exception: Throwable)
,就像Option[T]
总是Some[T](value: T)
或None
It can also be helpful to use the Scala REPL for things like this.将 Scala REPL 用于此类事情也很有帮助。 It allows you to easily see types.它使您可以轻松查看类型。
I'm assuming you've done this:我假设你已经这样做了:
scala> import scala.concurrent.Future
import scala.concurrent.Future
scala> import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.ExecutionContext.Implicits.global
scala> import scala.util.{Failure, Success}
import scala.util.{Failure, Success}
Now you have your two lines:现在你有你的两行:
scala> val a = Future { Thread.sleep(10*1000); 42 }
val a: scala.concurrent.Future[Int] = Future(<not completed>)
scala> val b = a.map(_ * 2)
val b: scala.concurrent.Future[Int] = Future(<not completed>)
As you can see the type of b
is still of scala.concurrent.Future[Int]
as it maps the result of a
, an Int
, which happens to be 42
, using the function (_: Int -> _ * 2):Int
.正如可以看到的类型b
是仍然scala.concurrent.Future[Int]
作为它映射的结果a
,一个Int
,这恰好是42
,使用功能(_: Int -> _ * 2):Int
。
And eventually:最终:
scala> b
val res0: scala.concurrent.Future[Int] = Future(Success(84))
From this documentation of Scala Future
s :从这个 Scala Future
s 的文档中:
Notice that the 84 you expected is wrapped in a
Success
, which is further wrapped in aFuture
.请注意,您期望的 84 包含在Success
,而后者又包含在Future
。 This is a key point to know: The value in aFuture
is always an instance of one of theTry
types:Success
orFailure
.这是要知道的关键点:Future
的值始终是Try
类型之一的实例:Success
或Failure
。 Therefore, when working with the result of a future, use the usualTry
-handling techniques, or one of the other Future callback methods.因此,在处理 Future 的结果时,请使用通常的Try
技术或其他 Future 回调方法之一。
Finally, to extract the Try
from the future, either a Success
or a Failure
, from which we will get our result, or an error:最后,从未来中提取Try
,无论是Success
还是Failure
,我们都会从中获得结果或错误:
scala> b.onComplete {
| case Success(value) => println(s"Got the callback, value = $value")
| case Failure(e) => e.printStackTrace
| }
Got the callback, value = 84
You are mixing two things here.你在这里混合了两件事。 When you create a Future
, it is created using the apply function which is in the companion object of Future
:当您创建Future
,它是使用Future
伴随对象中的 apply 函数创建的:
def apply[T](body: =>T)(implicit @deprecatedName('execctx) executor: ExecutionContext): Future[T] =
unit.map(_ => body)
So as long as the future is not completed, its type is Future[Int]
.所以只要未来没有完成,它的类型就是Future[Int]
。 Once the future completes, the result type will be Future[Try[Int]]
.一旦未来完成,结果类型将为Future[Try[Int]]
。
As stated on onComplete
documentation:如onComplete
文档所述:
When this future is completed, either through an exception, or a value, apply the provided function.当这个未来完成时,通过异常或值,应用提供的函数。
Therefore when you printed the completed future, it already had the Success.因此,当您打印完成的未来时,它已经有了成功。 If you will do the same experiment with a longer wait, and an uncompleted future you will see that its type is not yet success.如果你用更长的等待时间做同样的实验,还有一个未完成的未来,你会看到它的类型还没有成功。
For example, the following code:例如,以下代码:
implicit val ec = scala.concurrent.ExecutionContext.global
val a = Future { Thread.sleep(10*1000); 42 }
println(a)
Await.result(a, Integer.MAX_VALUE.seconds)
println(a)
will output:将输出:
Future(<not completed>)
Future(Success(42))
You can see that example running here .您可以在此处看到该示例运行。
Let's now look at onComplete .现在让我们看看onComplete 。 The following code:以下代码:
val a = Future { Thread.sleep(10*1000); 42 }
a.onComplete {
case Success(value) =>
println(value)
case Failure(exception) =>
println(exception)
}
val b = Future { throw new RuntimeException }
b.onComplete {
case Success(value) =>
println(value)
case Failure(exception) =>
println(exception)
}
Await.result(a, Integer.MAX_VALUE.seconds)
Await.result(b, Integer.MAX_VALUE.seconds)
Here we can see an example how to use onComplete
when a
should complete successfully, and b
should throw, and this is exactly what we get.在这里我们可以看到一个例子,当a
应该成功完成,而b
应该抛出时,如何使用onComplete
,这正是我们得到的。 The output is:输出是:
java.lang.RuntimeException
42
Because the throwingFuture is completed first, it is printed first.因为 throwingFuture 先完成,所以先打印。
The documentation says that a Future[B]
contains a Try[B]
, which is correct.文档说Future[B]
包含Try[B]
,这是正确的。 I think you're getting confused by the toString
representation here: Future(Success(84))
is the textual representation of a Future[Int]
.我认为您对这里的toString
表示感到困惑: Future(Success(84))
是Future[Int]
的文本表示。 For a Future[Try[Int]]
, you would have Future(Success(Success(84)))
as the textual representation.对于Future[Try[Int]]
,您将Future(Success(Success(84)))
作为文本表示。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.