为什么我可以写
val flat: List[Int] = List(Some(1), Some(2)).flatMap(i => i)
但不是
val flat: List[Int] = List(Some(1), Some(2)).flatMap(_)
下划线是变量的占位符。它本身不是一个函数。 flatMap
需要一个函数。
此外,在这种情况下,有一个flatten
方法,该方法是在List
上定义的,Option
在Predef
中具有隐式转换,以便您编写的内容可以压缩到该调用中,List(Some(1)).flatten
根据下划线的规则,List(Some(1), Some(2)).flatMap(_)
是x => List(Some(1), Some(2)).flatMap(x)
的缩写,而不是List(Some(1), Some(2)).flatMap(x => x)
。
简短的回答是下划线可以指身份映射,例如 x => x
,但flatMap
需要映射到TraversableOnce[U]
,例如项目列表。
例如,List(1, 2).flatMap(Seq(_))
有效。 List(1, 2).map(_ + 2)
也有效。第一个只是身份映射,第二个将返回List(3, 4)
。
但是,如果在map
(多个运算符)的flatMap
中进行复杂的转换,则必须正确编写 lambda 函数,否则编译器无法正确推断类型。请参阅 Scala 意外无法确定扩展函数的类型。