chi*_*ity 5 lambda scala anonymous-function
这段代码
(1 to 30).foreach { x =>
println(x)
println
}
Run Code Online (Sandbox Code Playgroud)
做什么我期望:它打印每一个1来30,用空格穿插.我很清楚这里发生了什么,我想:我正在传递一个首先打印其参数的匿名函数,然后打印一个空白行.
我不明白的是为什么不这样做:
(1 to 30).foreach {
println _
println
}
Run Code Online (Sandbox Code Playgroud)
它看起来相当于我.下划线应代表该函数的第一个也是唯一的参数; 并且该函数打印其参数,然后打印一个空行.但是当我运行第二个版本时,我没有得到空白行.
是什么导致这种差异?
第一个变体很简单:
println上x.println(这将打印额外的换行符).使用第二个变体,您可以有效地告诉Scala执行此操作:
println().随后,对这个新创建的对象不执行任何操作.println参数(序列的元素).混淆源于假设println(x)并且println _是等价的.它们是不同的.该funcId _语法的基础上定义新的功能funcId,它是不一样的,调用函数使用"强调的说法"符号.
这里发生了很多事情。
首先,所有参数占位符语法只能在 lambda 定义的外括号内使用。它不能在您在 lambda 定义中执行的方法调用的括号内使用。
这里有一个例子来证明这一点。
val a = (1 to 10).map(_ + 1)
Run Code Online (Sandbox Code Playgroud)
这将起作用。
val b = (1 to 10).map(math.sin(_ + 1))
Run Code Online (Sandbox Code Playgroud)
这是行不通的。
因此,您的代码根本不使用参数占位符语法。相反,它使用部分应用函数。
例如
(1 to 10).foreach(println _)
Run Code Online (Sandbox Code Playgroud)
在功能上等于
val a = println (_ : Int)
(1 to 10).foreach(a)
Run Code Online (Sandbox Code Playgroud)
此外,当在 lambda 表达式中使用方法名称时,可以省略下划线。Scala 仍然会生成部分应用的方法。
所以
(1 to 10).foreach(println)
Run Code Online (Sandbox Code Playgroud)
等于
(1 to 10).foreach(println _)
Run Code Online (Sandbox Code Playgroud)
因此你的代码等于
val a = println (_ : Int)
(1 to 10).foreach{
a
a
}
Run Code Online (Sandbox Code Playgroud)
并且因为 {aa} 返回 a,所以它等于
val a = println (_ : Int)
(1 to 10).foreach(a)
Run Code Online (Sandbox Code Playgroud)