从 Try 到 Future 的 Scala 隐式转换
Scala implicit conversion from Try to Future
我试图在 Scala 的 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 }
type mismatch;
found : scala.concurrent.Future[Int]
required: scala.util.Try[?]
b <- Future { 10 }
^
Compilation Failed
另一方面,如果我删除关键字 yield
,它会起作用:
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent._
import scala.util._
for {
a <- Try(5)
b <- Future(10)
} { println(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)))
有人能解释一下为什么会这样吗?这是一个错误吗?还是我遗漏了什么?
ps。这与 Scala 2.11 和 2.12 中的行为相同。
foreach
return是Unit
类型;因此是 "common" 类型。
没有 yield
关键字,编译器将您的 for-comprehension 解释为:
Try(5).foreach(a => Future(10).foreach(b => println(a + b)))
您可以处理 Future
和 Try
(两个不同的单子),只要您将它们链接在 foreach
.
周围
如果你加yield
关键字,编译器会用flatMap
/map
解释你的for-comprehension;如下:
Try(5).flatMap(a => Future(10).map(b => a + b))
Try#flatMap
需要一个 Try
作为 return 类型的函数,但它得到了 Future
,使得整个函数无法编译。
TL;DR:foreach
不期望在链接期间匹配函数类型,因为它在所有情况下都是 returns Unit;这就是它编译的原因。
注意以下几点:
Try(5) map { a => Future(10) map { b => a + b } }
有效,因为 map
不需要展平类型;所以包装编译时使用不同的 "effects"。
扁平化不同的类型会使编译器失败;正如 flatMap
尝试做的那样。
我试图在 Scala 的 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 }
type mismatch;
found : scala.concurrent.Future[Int]
required: scala.util.Try[?]
b <- Future { 10 }
^
Compilation Failed
另一方面,如果我删除关键字 yield
,它会起作用:
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent._
import scala.util._
for {
a <- Try(5)
b <- Future(10)
} { println(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)))
有人能解释一下为什么会这样吗?这是一个错误吗?还是我遗漏了什么?
ps。这与 Scala 2.11 和 2.12 中的行为相同。
foreach
return是Unit
类型;因此是 "common" 类型。
没有 yield
关键字,编译器将您的 for-comprehension 解释为:
Try(5).foreach(a => Future(10).foreach(b => println(a + b)))
您可以处理 Future
和 Try
(两个不同的单子),只要您将它们链接在 foreach
.
如果你加yield
关键字,编译器会用flatMap
/map
解释你的for-comprehension;如下:
Try(5).flatMap(a => Future(10).map(b => a + b))
Try#flatMap
需要一个 Try
作为 return 类型的函数,但它得到了 Future
,使得整个函数无法编译。
TL;DR:foreach
不期望在链接期间匹配函数类型,因为它在所有情况下都是 returns Unit;这就是它编译的原因。
注意以下几点:
Try(5) map { a => Future(10) map { b => a + b } }
有效,因为 map
不需要展平类型;所以包装编译时使用不同的 "effects"。
扁平化不同的类型会使编译器失败;正如 flatMap
尝试做的那样。