在此代码中:
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
参数? file参数是否隐式传递给recursiveListFiles
?
答案 0 :(得分:1)
不,因为展开的flatMap
看起来像:
flatMap(file => recursiveListFiles(file))
因此,file
中的每个these
都会映射到Array[File]
,flatMap
会在{{1}}中展平。这里没有隐含的魔法(就像你要问的那样)。
答案 1 :(得分:0)
flatMap
使用函数f: (A) ⇒ GenTraversableOnce[B]
返回List[B]
。
在您的情况下,recursiveListFiles
为File ⇒ Array[File]
因此返回List[File]
。然后将生成的List[File]
连接到these
。
答案 2 :(得分:0)
排序。 flatMap
非常明确地将参数传递给它自己的参数。这是高阶函数的本质 - 你基本上给它一个回调,它调用回调,然后它对结果做了一些事情。唯一隐含的事情是将方法转换为函数类型。
任何方法都可以转换为等效的函数类型。因此,def recursiveListFiles(f: File): Array[File]
相当于File => Array[File]
,这很棒,因为在Array[File]
上,您有flatMap[B](f: File => Array[B]): Array[B]
,并且您的方法的函数类型完全适合:类型参数{{1 }被选为B
。
如另一个答案中所述,您可以通过执行以下操作显式创建该功能:
File
或
these.filter(_.isDirectory).flatMap(file => recursiveListFiles(file))
或
these.filter(_.isDirectory).flatMap(recursiveListFiles(_))
在更复杂的情况下,您可能需要使用其中一个更详细的选项,但在您的情况下,无需费心。