在 scala 中,为什么 list.flatMap(List) 不起作用?

In scala, why doesn't list.flatMap(List) work?

这个效果很好

val l = List(1,2,3)
l.flatMap(x => List(x))

但这行不通:

l.flatMap(List)

这也行不通:

l.flatmap(List.apply _)

有人对此有想法吗?谢谢!

这是因为List.apply使用可变参数:

def apply[A](xs: A*): List[A]

您正在寻找一种将单个项目转换为仅包含该项目的列表的方法。在 List 对象上没有专门的方法。相反,它们提供了一种更通用的方法,可以接受任意数量的参数,从而使您的第一个语句 (List(1, 2, 3)) 起作用。

您需要提供括号来创建仅包含一个对象的 List,因此在使用 _ 通配符引用 apply 方法时您需要做同样的事情:

val listOfOne = List(1)

l.flatMap(List(_))
l.flatMap(List.apply(_))

对于 List[A]flatMap 需要来自 A => GenTraversableOnce[B] 的函数。在该特定语法中使用 List.apply 的问题在于 apply 允许重复参数 A*,这是 Seq[A] 的语法糖。所以List.apply实际上是一个Seq[A] => List[A],它和A => List[A]是不一样的。我们可以在错误消息中看到:

scala> l.flatMap(List.apply)
<console>:9: error: polymorphic expression cannot be instantiated to expected type;
 found   : [A]Seq[A] => List[A]
 required: Int => scala.collection.GenTraversableOnce[?]
              l.flatMap(List.apply)

你能做的就是明确你只使用一个参数:

scala> l.flatMap(List(_))
res5: List[Int] = List(1, 2, 3)

scala> l.flatMap(List.apply(_))
res6: List[Int] = List(1, 2, 3)

l.flatMap(List) 永远无法工作,因为 List 是一个 class,Scala 不会用 apply 糖来处理它来生成 l.flatMap(List.apply) .