好吧,for
理解在它们看起来的方式上具有欺骗性。您的理解扩展为:
res.flatMap(opt => opt.map(r => print(!r))
这显然是错误的,因为您flatMap
期望返回类型Future[T]
为Option[Unit]
虽然有时,为了代码整洁,您可能希望有一个for
包含许多此类表达式的循环。在这些情况下,您可以:
scala> implicit def toFuture[T](t: => T):Future[T] = {
| val p = Promise[T]()
| p.tryComplete(Try(t))
| p.future
| }
scala> for {
| opt <- res
| r <- opt
| } yield {print(!r)}
false
以上产生:
res.flatMap[Option[Unit]](((opt: Option[Boolean]) =>
toFuture[Option[Unit]](opt.map[Unit](((r: Boolean) => print(!r))))))
编辑:虽然如果你使用yield
. 如果您不希望将for
理解用作表达式,那么您可以根据需要进行操作:
scala> val i = Future(Some(true))
i: scala.concurrent.Future[Some[Boolean]] = scala.concurrent.impl.Promise$DefaultPromise@6b24a494
scala> val j = Option(1)
j: Option[Int] = Some(1)
scala> val k = Right(1).right
k: scala.util.Either.RightProjection[Nothing,Int] = RightProjection(Right(1))
scala>
| for{
| x <- i
| y <- j
| z <- k
| }{
| println(i,j,k)
| }
(scala.concurrent.impl.Promise$DefaultPromise@6b24a494,Some(1),RightProjection(Right(1)))
这种方式不需要隐式。正如编译器foreach
在每个连接处使用的那样。-Xprint:typer
给出:
i.foreach[Unit](((x: Option[Boolean]) =>
j.foreach[Any](((y: Int) =>
k.foreach[Unit](((z: Int) => println(scala.this.Tuple3.apply[scala.concurrent.Future[Option[Boolean]], Option[Int], Either.RightProjection[Nothing,Int]](i, j, k))))))))
}