Scala 未来 return 类型
Scala Future return Type
我有以下几行代码...
val a = Future { Thread.sleep(10*1000); 42 }
val b = a.map(_ * 2)
一段时间后,当我检查 b 的值时,我打印了以下内容。
scala.concurrent.Future[Int] = Future(Success(84))
如上,b的类型是Future[Int];但在文档中,它说 Future 的应用方法总是 returns Future(Try[T])。文档和上面的例子相矛盾。有人可以帮忙吗
文档说 Future[B]
包含 Try[B]
,这是正确的。我认为您对此处的 toString
表示感到困惑:Future(Success(84))
是 Future[Int]
的文本表示。对于 Future[Try[Int]]
,您将使用 Future(Success(Success(84)))
作为文本表示。
你在这里混合了两种东西。当您创建 Future
时,它是使用 companion object of Future
:
中的应用函数创建的
def apply[T](body: =>T)(implicit @deprecatedName('execctx) executor: ExecutionContext): Future[T] =
unit.map(_ => body)
所以只要future没有完成,它的类型就是Future[Int]
。 Future 完成后,结果类型将为 Future[Try[Int]]
.
如 onComplete
文档所述:
When this future is completed, either through an exception, or a value, apply the provided function.
因此当你打印完成的未来时,它已经成功了。如果您将等待更长的时间和未完成的未来进行相同的实验,您会发现它的类型尚未成功。
例如下面的代码:
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)
将输出:
Future(<not completed>)
Future(Success(42))
你可以看到那个例子 运行 here.
现在让我们看看onComplete。以下代码:
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)
这里我们可以看到一个例子,当 a
应该成功完成,b
应该抛出错误时,如何使用 onComplete
,这正是我们得到的结果。输出为:
java.lang.RuntimeException
42
因为throwingFuture先完成,所以先打印。
请post你的导入和你引用的文档。
我认为与理解这一点最相似的是:
Try[T]
就像 Option[T]
,Try[T]
总是 Success[T](value: T)
或 Failure[T](exception: Throwable)
,就像 Option[T]
总是 Some[T](value: T)
或 None
对于这样的事情,使用 Scala REPL 也很有帮助。它可以让您轻松查看类型。
我假设你已经这样做了:
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}
现在你有两条线:
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>)
如您所见,b
的类型仍然是 scala.concurrent.Future[Int]
,因为它映射了 a
的结果,一个 Int
,恰好是 42
, 使用函数 (_: Int -> _ * 2):Int
.
最终:
scala> b
val res0: scala.concurrent.Future[Int] = Future(Success(84))
来自 this documentation of Scala Future
s:
Notice that the 84 you expected is wrapped in a Success
, which is further wrapped in a Future
. This is a key point to know: The value in a Future
is always an instance of one of the Try
types: Success
or Failure
. Therefore, when working with the result of a future, use the usual Try
-handling techniques, or one of the other Future callback methods.
最后,要从未来提取 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
我有以下几行代码...
val a = Future { Thread.sleep(10*1000); 42 }
val b = a.map(_ * 2)
一段时间后,当我检查 b 的值时,我打印了以下内容。
scala.concurrent.Future[Int] = Future(Success(84))
如上,b的类型是Future[Int];但在文档中,它说 Future 的应用方法总是 returns Future(Try[T])。文档和上面的例子相矛盾。有人可以帮忙吗
文档说 Future[B]
包含 Try[B]
,这是正确的。我认为您对此处的 toString
表示感到困惑:Future(Success(84))
是 Future[Int]
的文本表示。对于 Future[Try[Int]]
,您将使用 Future(Success(Success(84)))
作为文本表示。
你在这里混合了两种东西。当您创建 Future
时,它是使用 companion object of Future
:
def apply[T](body: =>T)(implicit @deprecatedName('execctx) executor: ExecutionContext): Future[T] =
unit.map(_ => body)
所以只要future没有完成,它的类型就是Future[Int]
。 Future 完成后,结果类型将为 Future[Try[Int]]
.
如 onComplete
文档所述:
When this future is completed, either through an exception, or a value, apply the provided function.
因此当你打印完成的未来时,它已经成功了。如果您将等待更长的时间和未完成的未来进行相同的实验,您会发现它的类型尚未成功。
例如下面的代码:
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)
将输出:
Future(<not completed>)
Future(Success(42))
你可以看到那个例子 运行 here.
现在让我们看看onComplete。以下代码:
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)
这里我们可以看到一个例子,当 a
应该成功完成,b
应该抛出错误时,如何使用 onComplete
,这正是我们得到的结果。输出为:
java.lang.RuntimeException
42
因为throwingFuture先完成,所以先打印。
请post你的导入和你引用的文档。
我认为与理解这一点最相似的是:
Try[T]
就像 Option[T]
,Try[T]
总是 Success[T](value: T)
或 Failure[T](exception: Throwable)
,就像 Option[T]
总是 Some[T](value: T)
或 None
对于这样的事情,使用 Scala REPL 也很有帮助。它可以让您轻松查看类型。
我假设你已经这样做了:
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}
现在你有两条线:
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>)
如您所见,b
的类型仍然是 scala.concurrent.Future[Int]
,因为它映射了 a
的结果,一个 Int
,恰好是 42
, 使用函数 (_: Int -> _ * 2):Int
.
最终:
scala> b
val res0: scala.concurrent.Future[Int] = Future(Success(84))
来自 this documentation of Scala Future
s:
Notice that the 84 you expected is wrapped in a
Success
, which is further wrapped in aFuture
. This is a key point to know: The value in aFuture
is always an instance of one of theTry
types:Success
orFailure
. Therefore, when working with the result of a future, use the usualTry
-handling techniques, or one of the other Future callback methods.
最后,要从未来提取 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