试图理解为什么以下表达式产生Future [Nothing]而不是Future [List [Int]]
def foo(): Future[List[Int]] = Future(List(1,2,3,3,3,4,4,4))
def bar(): Future[Nothing] =for {
fooList <- foo()
f <- fooList.distinct
} yield f
当然,这是简化示例,我可以直接返回fooList。但我想了解获取Future[Nothing]
而不是Future[List[Int]]
答案 0 :(得分:7)
我的代码出现了编译器错误,这是预期的,因为fooList.distinct
应该是Future
,因为提取器<-
可以使用它。
scala> def foo() = Future(List(1,2,2,3))
foo: ()scala.concurrent.Future[List[Int]]
scala> for(fooList <- foo(); f <- fooList.distinct) yield f
<console>:17: error: type mismatch;
found : List[Int]
required: scala.concurrent.Future[?]
for(fooList <- foo(); f <- fooList.distinct) yield f
^
此代码编译:
scala> for(fooList <- foo(); f = fooList.distinct) yield f
res4: scala.concurrent.Future[List[Int]] = scala.concurrent.impl.Promise$DefaultPromise@1e387e13
此代码也(将distinct
的调用包装到Future中):
scala> for(fooList <- foo(); f <- Future(fooList.distinct)) yield f
res5: scala.concurrent.Future[List[Int]] = scala.concurrent.impl.Promise$DefaultPromise@623d211
res4: scala.concurrent.Future[List[Int]] = scala.concurrent.impl.Promise$DefaultPromise@1e387e13
答案 1 :(得分:3)
Scala的 for-comprehension 只是方法flatMap
,map
和filter
的语法糖。代码
for {
x1 <- e1
x2 = e2
x3 <- e3 if e4
x4 <- e5
} yield e6
转化为(或等同于)
e1.flatMap(x1 =>
e2.map(x2 =>
e3.filter(x3 => e4).flatMap(x3 =>
e5.map(x4 => e6)
示例中的 for-comprehension 变为
foo().flatMap(fooList => fooList.distinct.map(f => f))
相当于
foo().flatMap(fooList => fooList.distinct)
因map(id) = id
定义了Functor是什么。方法foo().flatMap
采用List[Int] ⇒ Future[S]
类型的参数。但函数fooList => fooList.distinct
的类型为List[Int] => List[Int]
。编译器检查提供的类型是否是预期类型的子类型。在您的情况下,检查属于: List[Int]
某种类型的 Future[S]
的子类型 {{1} }。我不确定为什么被请求的类型S
是S
,但它可能与Nothing
是协变的(因为任何Future
都应该)。
鉴于类型为Functor
的未来,Future[T]
和map
都会生成flatMap
,但区别在于:
Future[S]
接受map
类型的参数。 语法 T => S
。x = ...
接受flatMap
类型的参数。 语法 T => Future[S]
。您想要的方法是x <- ...
,它提供
map
或
for (fooList <- foo())
yield fooList.distinct