【问题标题】:Why does one of these statements compile in Scala but not the other?为什么这些语句中的一个可以在 Scala 中编译,而另一个不能?
【发布时间】:2011-02-03 13:08:33
【问题描述】:

注意:我在这里使用的是 Scala 2.7.7,而不是 2.8)。

我正在做一些非常简单的事情——根据一个简单的 2 列 CSV 文件中的值创建一个地图——而且我已经很容易地完成了它,但我很困惑为什么我的第一次尝试没有不编译。代码如下:

// Returns Iterator[String]
private def getLines = Source.fromFile(csvFilePath).getLines

// This doesn't compile:
def mapping: Map[String,String] = {
    Map(getLines map { line: String =>
          val pairArr = line.split(",")
          pairArr(0) -> pairArr(1).trim()
        }.toList:_*)
  }

// This DOES compile
def mapping: Map[String,String] = {
    def strPair(line: String): (String,String) = {
      val pairArr = line.split(",")
      pairArr(0) -> pairArr(1).trim()
    }
    Map(getLines.map( strPair(_) ).toList:_*)
  }

编译错误是

CsvReader.scala:16: 错误:值 toList 不是 (字符串) => (java.lang.String, java.lang.String) [scalac] 可能的 原因:可能缺少分号 在`value toList'之前? [scalac]
}.toList:_*) [scalac] ^
[scalac] 发现一个错误

那是什么?除了显式函数定义(与非工作示例中的匿名)和 () 与 {} 之外,它们似乎应该与我等价。如果我在非工作示例中用括号替换花括号,则错误为“';'预期,但找到了'val'。”但是,如果我删除局部变量定义并将字符串拆分两次并使用括号而不是花括号,它会编译。有人可以向我解释这种差异,最好是 Scala 文档的链接,解释用于包围方法参数时括号和花括号之间的区别?

【问题讨论】:

    标签: syntax scala


    【解决方案1】:

    看起来不同是因为您在第一个示例中使用了运算符表示法。如果您添加一组额外的括号,它会起作用:

    def mapping: Map[String,String] = {
        Map((getLines map { line: String =>
          val pairArr = line.split(",")
          pairArr(0) -> pairArr(1).trim()
        }).toList:_*)
    }
    

    或者如果你不使用它的操作符语法

    def mapping: Map[String,String] = {
        Map(getLines.map({ line: String =>
          val pairArr = line.split(",")
          pairArr(0) -> pairArr(1).trim()
        }).toList:_*)
    }
    

    我认为问题在于使用普通方法调用语法比方法调用的运算符语法具有更高的优先级。这意味着.toList 被应用于匿名函数,而不是map 方法调用的结果。

    【讨论】:

      【解决方案2】:

      如果你不使用操作符语法,它编译得很好:

      //Compiles
      def mapping: Map[String,String] = {
          Map(getLines.map { line: String =>
                val pairArr = line.split(",")
                pairArr(0) -> pairArr(1).trim()
              }.toList:_*)
        }
      

      你如何使用匿名函数没有问题,但正如 Ben 提到的,没有 . 的调用 map 的语法不等同于典型的 Java 风格的方法调用。

      【讨论】:

        猜你喜欢
        • 2010-09-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多