了解scala中的中缀行为

Ele*_*fee 2 scala language-theory infix-notation

不知道我是否应该在这里或程序员那里问这个问题,但无论如何

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

举个例子,你可以这样做:

lst foreach println // equivalent to lst.foreach(println)
Run Code Online (Sandbox Code Playgroud)

当然人们会认为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

Her*_*lme 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)
Run Code Online (Sandbox Code Playgroud)

  • `lst map(_.toString)`也是合法的; 你并不需要花括号 (4认同)