3

我正在 Eclipse 中使用 Scala-IDE 学习 Scala。在遵循第 9 章:控制抽象,第 1 部分:在 Scala 编程一书中减少代码重复的过程中,我已经编写了书中的代码(在下面完整展示),它运行良好!当我开始删除不必要的空行时,发生了一件奇怪的事情。以下是删除方法中的空行之前的完整代码filterFiles()

object Code_c09s01_ControlAbstraction extends App{

  object FilesFilter {

    private def filterFiles(path: String, pattern: String, matcher: (String, String) => Boolean) = {

      val files = (new java.io.File(path)) listFiles

      for(file <- files if matcher(file.getName, pattern)) yield file
    } 

    def filterExtension(path: String, pattern: String) = filterFiles(path, pattern, _.endsWith(_))
    def filterName(path: String, pattern: String) = filterFiles(path, pattern, _.contains(_))
    def filterRegex(path: String, pattern: String) = filterFiles(path, pattern, _.matches(_))
  }

  def printArray[A](message: String, arr: Array[A]) {
    println (message)
    println (arr mkString("\n"))
  }

  def test() {
    val path = "C:\\";

    printArray("--- filtering by ext: ---", FilesFilter.filterExtension(path, ".txt"))
    printArray("--- filtering by containment: ---", FilesFilter.filterName(path, "1"))
    printArray("--- filtering by regex: ---", FilesFilter.filterRegex(path, "."))
  }

  test

}

效果很好!但是,从方法中删除空行后filterFiles(),该方法现在看起来像这样:

private def filterFiles(path: String, pattern: String, matcher: (String, String) => Boolean) = {
  val files = (new java.io.File(path)) listFiles
  for(file <- files if matcher(file.getName, pattern)) yield file
} 

IDE 在正文的两行都给了我错误。第一行的错误说:

ambiguous reference to overloaded definition, both method listFiles in class File of type (x$1: java.io.FileFilter)Array[java.io.File] and method listFiles in class File of type 
 (x$1: java.io.FilenameFilter)Array[java.io.File] match argument types (Null)

第二行的错误说:

illegal start of simple expression

printArray()现在对方法中的所有三个调用test()也说明了这一点:

type mismatch; found : Unit required: Array[?]

这是什么意思呢?当代码对齐会破坏代码流时,Scala 不应该表现得像 Python 那样......那么为什么删除方法主体的第一行和第二行之间的空白行会导致filterFiles()如此严重的错误呢?它是某个地方的错误还是直接遵循 Scala 的规则?注意:如果我;在行之间添加,它会整理所有内容。它只是分号推断错误吗?

4

2 回答 2

4

当对象的方法可以没有参数或单个参数时,您可以像这样调用它

val files = object method arg

或者,在您的代码段中

val files = object method
  arg

在您的代码中,编译器希望listfiles使用一个for表达式作为返回的参数来调用Array[File]。并抱怨listFiles这种类型的论点没有实现。空行防止将for表达式视为listFiles函数的参数

于 2011-12-29T14:47:04.803 回答
2

正如您所建议的,看起来像分号推断问题,我猜如果您省略括号,编译器需要方法参数。您可以在 listFiles 之后添加括号,而不是分号:

val files = (new java.io.File(path)) listFiles ()
于 2011-12-29T14:46:18.750 回答