对 flatMap 的调用是否隐含?

Is there an implicit in this call to flatMap?

在此代码中:

import java.io.File
def recursiveListFiles(f: File): Array[File] = {
  val these = f.listFiles
  these ++ these.filter(_.isDirectory).flatMap(recursiveListFiles)
}

取自:How do I list all files in a subdirectory in scala?

为什么 flatMap(recursiveListFiles) 编译?因为 recursiveListFiles 接受 File 参数?文件参数是否隐式传递给 recursiveListFiles

否,因为展开的 flatMap 看起来像:

flatMap(file => recursiveListFiles(file))

因此 these 中的每个 file 都被映射到一个 Array[File],它在 flatMap 中被压平。这里没有隐含的魔法(以你问的方式)。

flatMap 接受函数 f: (A) ⇒ GenTraversableOnce[B] 到 return List[B].

在你的例子中,它是 recursiveListFiles,这是一个 File ⇒ Array[File],因此 return 是一个 List[File]。然后将此结果 List[File] 连接到 these.

有点。 flatMap 非常明确地将一个参数传递给它自己的参数。这是高阶函数的本质——你基本上给它一个回调,它调用回调,然后它对结果做一些事情。唯一隐含的事情是将方法转换为函数类型。

任何方法都可以转换为等效的函数类型。所以 def recursiveListFiles(f: File): Array[File] 等同于 File => Array[File],这很好,因为在 Array[File] 上,你有 flatMap[B](f: File => Array[B]): Array[B],并且你的方法的函数类型非常适合:类型参数 B 被选择为 File.

如另一个答案中所述,您可以通过以下方式显式创建该函数:

these.filter(_.isDirectory).flatMap(file => recursiveListFiles(file))these.filter(_.isDirectory).flatMap(recursiveListFiles(_))these.filter(_.isDirectory).flatMap(recursiveListFiles _)

在更复杂的情况下,您可能需要使用这些更冗长的选项之一,但在您的情况下,无需费心。