带有“_”(下划线)的匿名 Scala 函数的主体包含多少代码?

How much code does the body of an anonymous Scala function with "_" (underscore) comprise?

在 Scala 中,如果你有一个包含下划线的表达式,这是一个匿名函数,以表达式作为它的主体,下划线作为它的参数,例如2*_ 是将参数加倍的匿名函数。但是函数体延伸多远呢?我在这里遗漏了一条明确的规则,可以消除诸如以下(使用 Scala 2.11.7 REPL 测试):

scala> (_: Int)+2-1  // function body up to 1 - OK
res7: Int => Int = <function1>

scala> ((_: Int)+2)-1  // function body up to 2, - applied to function is an error
<console>:11: error: value - is not a member of Int => Int
   ((_: Int)+2)-1
               ^
((_: Int)+2)-1  // function body up to 2, - applied to function is an error 

error: value - is not a member of Int => Int
   ((_: Int)+2)-1

编译器的错误信息是合理的。您的附加括号创建了一个函数文字,将“2”添加到 wildcard/placeholder 参数。编译器读取您的代码意味着您有一个 this 函数值,并且您正试图从中减去“1”。

这没有意义。您可以从其他数字中减去“1”,但肯定不是函数值。因此,编译器告诉您从函数值中减一是没有意义的。或者,在编译器术语中,Int => Int 类型的函数没有“-”函数。

value - is not a member of Int => Int

要理解此错误消息,您需要知道 Scala 中的所有运算符(-、*、+ 等)都是作为类型的方法实现的。如果您查看 Scala API docs for Int,您会发现它定义了一长串方法,其中常用数学和逻辑运算符符号作为函数名称。

http://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html#placeholder-syntax-for-anonymous-functions中给出了定义,它...不是那么简单。

An expression e of syntactic category Expr binds an underscore section u, if the following two conditions hold: (1) e properly contains u, and (2) there is no other expression of syntactic category Expr which is properly contained in e and which itself properly contains u.

If an expression e binds underscore sections u_1 , \ldots , u_n, in this order, it is equivalent to the anonymous function (u'_1, ... u'_n) => e' where each u_i' results from u_i by replacing the underscore with a fresh identifier and e' results from e by replacing each underscore section u_i by u_i'.

如果您查看本节开头的语法,(_: Int)+2-1 中的 (_: Int)+2 不是 Expr,但 ((_: Int)+2)-1 中的是。