2012-12-20 19 views
13

使用for循环用一个简单的选件上工作:为什么Option在循环内需要显式toList?

scala> for (lst <- Some(List(1,2,3))) yield lst 
res68: Option[List[Int]] = Some(List(1, 2, 3)) 

但遍历选项的内容不会:

scala> for (lst <- Some(List(1,2,3)); x <- lst) yield x 
<console>:8: error: type mismatch; 
found : List[Int] 
required: Option[?] 
       for (lst <- Some(List(1,2,3)); x <- lst) yield x 
              ^

...除非该选项被明确地转换为一个列表:

scala> for (lst <- Some(List(1,2,3)).toList; x <- lst) yield x 
res66: List[Int] = List(1, 2, 3) 

为什么需要显式列表转换?这是惯用的解决方案吗?

回答

12
for (lst <- Some(List(1,2,3)); x <- lst) yield x 

被翻译成

Some(List(1,2,3)).flatMap(lst => lst.map(x => x)) 

OptionflatMap方法要求返回Option的功能,但你传递一个返回List的功能并没有从List没有隐式转换Option

现在,如果你转换Option到列表第一,ListflatMap方法将改为调用,它需要一个函数返回一个List,这是要传递什么吧。

在这种特殊情况下,我认为最惯用的解决方案是

Some(List(1,2,3)).flatten.toList 
+0

这就是为什么'的(LST < - 一些(名单(1,2,3))获得; X < - 选项(LST ))产量x'也有效。有趣。 – sberry

相关问题