我不确定我是在这里还是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
的简单规则不再适用?
答案 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)