正确的做法如下
List(1,2,3,4).map("*" * _).foreach(println)
在 scala 中有许多不同的下划线用例。我在这里列出了与这个问题相关的三个用例。
案例 1:在输入参数中使用下划线
当输入参数不用于 lambda 表达式的主体时,您可以使用下划线作为 lambda 表达式的参数,因此您可以使用下划线作为占位符,而不是将 lambda 表达式的输入参数声明为如下图所示。
List(1,2,3,4).foreach(_ => println("*" * 10)) // here 10 '*' characters are displayed irrespective of the input value.
案例 2:在 lambda 表达式主体中使用下划线。
当在 lambda 表达式的主体中使用下划线时,它指的是输入参数。如果输入仅被引用一次,您可以以这种方式使用下划线。
例如:List(1,2,3,4).foreach(println("*" * _)) // the underscore will be subsituted with the input argument.
案例 3:引用未应用的方法。
假设我有一个方法foo(bar: Int)。我可以通过表达式foo _ 来引用未应用的方法方法(即foo 紧跟一个下划线)。
此处未应用的函数意味着获取对稍后可以按需执行的函数对象的引用。
@ def foo(bar: Int) = bar
defined function foo
@ val baz = foo _
baz: Int => Int = $sess.cmd24$$$Lambda$2592/612249759@73fbe2ce
@ baz.apply(10)
res25: Int = 10
您不能混合使用案例 1 和案例 2。即,您可以在输入参数或 lambda 函数的主体中使用下划线,但不能在两者中使用。由于您混合了这两种情况,因此您意外地使用了下划线用法的情况 3,如下所示。即您指的是通过java.lang.String 上的隐式定义的未应用方法*。
@ "*" * _
res20: Int => String = $sess.cmd20$$$Lambda$2581/1546372166@20967474
你正在做的事情就像下面这样。
List(1,2,3,4).foreach(x => println(("*" * _).toString))