为何使用(x => x)可避免解构Option列表时出现错误?
为什么两个flatMap调用表现不同?
先看你给出的第一个代码示例:
List(Some(3), None, Some(4)).flatMap { case Some(n) => List(n) case _ => Nil // 此分支是必需的(否则会抛出MatchError) } // List(3, 4)
这里传给flatMap的是一个偏函数(PartialFunction)——用花括号包裹的case语句定义的函数。偏函数只对部分输入值有效,若输入不在它的处理范围内就会抛出MatchError。如果去掉case _ => Nil分支,遇到None时没有对应的匹配规则,自然触发错误;加上兜底分支后,None被映射成空列表Nil,flatMap处理空列表时不会产生元素,最终结果正常。
再看第二个示例:
List(Some(3), None, Some(4)).flatMap(x => x) // List(3, 4)
这里传给flatMap的是普通函数x => x,输入和输出都是Option[Int]。Scala的flatMap要求传入函数返回可遍历的集合类型(具体是GenTraversableOnce特质),而Option恰好实现了这个特质:
Some(n)会被视为只包含元素n的单元素集合None会被视为空集合
当flatMap处理None时,会把这个空集合展开,不会产生任何元素,因此整个过程不会报错,最终结果就是提取所有Some中的元素、忽略None。
核心区别总结:第一个用了未覆盖全量输入的偏函数,第二个用了普通函数,且Option本身符合flatMap对返回值的要求。
内容的提问来源于stack exchange,提问作者nachocab
相关产品推荐
相关产品推荐

