两个新手问题。
看来for
理解知道Options
,并且可以自动跳过None
和UNWRAP Some
,例如。
val x = Map("a" -> List(1,2,3), "b" -> List(4,5,6), "c" -> List(7,8,9))
val r = for {map_key <- List("WRONG_KEY", "a", "b", "c")
map_value <- x get map_key } yield map_value
输出:
r: List[List[Int]] = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9))
Options
去哪儿?有人可以阐明这项工作吗?我们可以始终依靠这种行为吗?
第二件事是为什么它不编译?
val x = Map("a" -> List(1,2,3), "b" -> List(4,5,6), "c" -> List(7,8,9))
val r = for {map_key <- List("WRONG_KEY", "a", "b", "c")
map_value <- x get map_key
list_value <- map_value
} yield list_value
它给出
Error:(57, 26) type mismatch;
found : List[Int]
required: Option[?]
list_value <- map_value
^
查看第一个示例的类型,我不确定为什么我们需要在这里有一个Option
?
用于综合的
将转换为呼叫,以呼叫以MAP或FLATMAP调用的顺序。请参阅此处
您的for
环相当于
List("WRONG_KEY", "a", "b", "c").flatMap(
map_key => x.get(map_key).flatMap(map_value => map_value)
)
Option
中的flatMap
定义为
@inline final def flatMap[B](f: A => Option[B]): Option[B]
因此,由于编译器通知您,因此不允许将List
作为参数传递。
我认为区别是由于综合的方式扩展到seq特征中的映射((和flatmap方法调用。
为了简洁,让我们定义一些变量:
var keys = List("WRONG_KEY", a, b, c)
您的第一种情况等效于:
val r = keys.flatMap(x.get(_))
您的第二种情况相当于:
val r= keys.flatMap(x.get(_).flatMap{ case y => y })
我认为问题是该option.flatmap((应该返回一个选项[],在第一种情况下很好,但在第二种情况下与x.get((。flatmap传递的内容不一致,这是列表[int]。
Wampler&amp;Payne。
也许这种很小的差异,设置括号并弄平了,使其清晰:
val r = for {map_key <- List("WRONG_KEY", "a", "b", "c")
| } yield x get map_key
r: List[Option[List[Int]]] = List(None, Some(List(1, 2, 3)), Some(List(4, 5, 6)), Some(List(7, 8, 9)))
val r = (for {map_key <- List("WRONG_KEY", "a", "b", "c")
| } yield x get map_key).flatten
r: List[List[Int]] = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9))
那等同于:
scala> List("WRONG_KEY", "a", "b", "c").map (x get _)
res81: List[Option[List[Int]]] = List(None, Some(List(1, 2, 3)), Some(List(4, 5, 6)), Some(List(7, 8, 9)))
scala> List("WRONG_KEY", "a", "b", "c").map (x get _).flatten
res82: List[List[Int]] = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9))
中间值(map_key(在第二块中消失了。
您正在将两个不同的单子(List
和Option
(混合在供语句中。这有时可以按预期工作,但并非总是如此。无论如何,您都可以自己列入列表:
for {
map_key <- List("WRONG_KEY", "a", "b", "c")
list_value <- x get map_key getOrElse Nil
} yield list_value