了解scala中的中缀行为

时间:2014-06-10 09:55:57

标签: scala infix-notation language-theory

我不确定我是在这里还是Programmers上问这个问题,但无论如何

在Scala中,可以使用中缀语法编写方法调用,即省略点和parens。

作为一个例子,你可以这样做:

lst foreach println // equivalent to lst.foreach(println)

当然人们会认为lst map _.toString会被评估为lst.map(_.toString),相当于lst.map(x$1 => x$1.toString)

但是将lst map _.toString放入repl会产生令人惊讶的结果,它被评估为((x$1) => sList.map(x$1.toString)),导致方法调用失灵。

那为什么呢?为什么在撰写a.f(b)a f b等同于a f _.b的简单规则不再适用?

1 个答案:

答案 0 :(得分:5)

因为表达式含糊不清。

来自Scala(有点过时)规范P94:http://www.scala-lang.org/docu/files/ScalaReference.pdf

  

表达式(语法类别Expr)可能在标识符合法的位置包含嵌入的下划线符号_。这样的表达式表示一个匿名函数,其中后续出现的下划线表示连续的参数。

由于lst map _.toString是一个合法的表达式,它自然可以被评估为像(x) => lst.map(x.toString)这样的匿名函数。

您仍然可以使用大括号表达式使得Scala编译器首先评估占位符函数。

scala> val lst = List(1,2,3,4,5)
lst: List[Int] = List(1, 2, 3, 4, 5)

scala> lst map { _.toString }
res43: List[String] = List(1, 2, 3, 4, 5)