Scala从Try到Future的隐式转换
我试图在Scala中的Scala从Try到Future的隐式转换,scala,for-loop,future,implicit-conversion,implicit,Scala,For Loop,Future,Implicit Conversion,Implicit,我试图在Scala中的for循环中将Trys与Futures混合,而不显式地将Trys转换为Futures与Future.fromTry。看起来它在某些情况下会自动工作,但在其他情况下不会 以下代码段在以下情况下失败: import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent._ import scala.util._ for { a <- Try(5) b <- Fu
for
循环中将Try
s与Future
s混合,而不显式地将Try
s转换为Future
s与Future.fromTry
。看起来它在某些情况下会自动工作,但在其他情况下不会
以下代码段在以下情况下失败:
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent._
import scala.util._
for {
a <- Try(5)
b <- Future(10)
} yield { a + b }
当我将for
循环重写为嵌套的foreach
或map
时,它也会起作用:
@ Try(5) foreach { a => Future(10) foreach { b => println(a + b) } }
15
@ Try(5) map { a => Future(10) map { b => a + b } }
res5: Try[Future[Int]] = Success(Future(Success(15)))
有人能解释一下为什么会这样吗?这是虫子吗?还是我遗漏了什么
注:Scala 2.11和2.12中的行为相同。
foreach
返回一个单元
类型;因此是一种“普通”类型
如果没有yield
关键字,编译器会将您的理解解释为:
Try(5).foreach(a => Future(10).foreach(b => println(a + b)))
您可以处理未来
和尝试
(两个不同的单子),只要您将它们链接到foreach
如果您添加yield
关键字,编译器将使用flatMap
/map
对您进行解释以供理解;详情如下:
Try(5).flatMap(a => Future(10).map(b => a + b))
Try#flatMap
需要一个返回类型为Try
的函数,但它得到了一个Future
,使得整个函数不可编译
TL;DR:foreach
不希望在链接期间匹配函数类型,因为它在所有情况下都返回单元;这就是它编译的原因。
请注意:
Try(5) map { a => Future(10) map { b => a + b } }
因为map
不需要展平类型,所以可以工作;因此,包装会产生不同的“效果”。
展平不同类型会导致编译器失败;正如flatMap
尝试做的那样
Try(5) map { a => Future(10) map { b => a + b } }