首页 > 解决方案 > (println _) 中的下划线占位符如何表示其原始函数字面量的整个参数列表?

问题描述

我试图举一个例子来解释不带括号的占位符 _ 可以表示(扩展为)任意数量的任何类型的参数,而不仅仅是可以表示任何类型的“仅一个”参数。但是,我做的那个是不正确的,因为 foreach 的参数(函数文字)仍然只需要一个参数。
// 下面解释上面占位符规则的代码是不正确的。
我做了一个修改的例子来简单说明这个规则。

val list1 = List(1,2,3)
val list2 = List((1,2),(3,4),(5,6))
val list3 = List((1,2,3),(4,5,6),(7,8,9))
scala> list1.foreach(println _) // _ is expanded to 1 parameter in each iteration
1
2
3

scala> list2.foreach(println _) // _ is expanded to 2 parameters in each iteration
(1,2)
(3,4)
(5,6)

scala> list3.foreach(println _) // _ is expanded to 3 parameters in each iteration
(1,2,3)
(4,5,6)
(7,8,9)

这也许可以更清楚地解释规则。
我希望它是正确的。

// 原问题
在 Programming in Scala, 3rd Edition 一书的第 8.6 章部分应用函数中,示例显示:

val list = List(1,2,3)
list.foreach(x => println(x))

上下文说函数字面量

println _

可以代替

x => println(x)

因为 _ 可以代表整个参数列表。

我知道下划线在其自身和函数名称(在本例中为 println)之间留有空格意味着下划线代表整个参数列表。
然而,在这种情况下,原始函数字面量中只有一个参数(每次迭代的 Int 元素)。
为什么本教程说 _ 代表整个参数列表?

函数字面量

x => println(x) // Only one parameter? Where's the entire parameter list? 

list.foreach(x => println(x))

显然只有一个参数,对吗?

标签: scalaplaceholderfunction-literal

解决方案


为什么本教程说 _ 代表整个参数列表?

因为它谈论的是整个参数列表println其中只有一个参数。

你的意思是 println _ 代表 println(element1: Int, element2: Int, ... elementN: Int)

没有。要确定含义println _我们看它的签名

def println(x: Any): Unit

“整个参数列表”是(x: Any),所以println _与 相同(x: Any) => println(x)。如果你有def foo(x: Int, y: Int) = x + y,那么foo _就会(x: Int, y: Int) => foo(x, y)

注意:也有无参数的重载def println(): Unit,但编译器认为这里没有意义,因为foreach需要一个带有单个参数的函数;但例如在

val f: () => Unit = println _

println _相当于() => println()代替(x: Any) => println(x)


推荐阅读