【问题标题】:Scala-IDE or Scala unjustified syntax ambiguityScala-IDE 或 Scala 不合理的语法歧义
【发布时间】:2012-01-29 22:24:09
【问题描述】:

我正在 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

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

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

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

【问题讨论】:

  • 它与 Python 不同,您不必必须依赖对齐或空格:例如,您可以在每个语句的末尾添加分号。跨度>
  • 是的,这绝对是要记住的事情。

标签: scala syntax inference scala-ide


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    val files = object method arg
    

    或者,在你的 sn-p 中

    val files = object method
      arg
    

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

    【讨论】:

    • 嗯,我没有注意到在任何其他相关语言中空行可以做这种伎俩。有点令人费解的经历)
    • Scala IDE 有一个名为show inferred semicolons 的功能,它在当前编辑器中添加了推断的分号。这有助于解决此类错误。
    猜你喜欢
    • 2012-05-03
    • 1970-01-01
    • 1970-01-01
    • 2013-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多