任何人都可以解释我为什么这样做:
a.mapValues(_.size)
Run Code Online (Sandbox Code Playgroud)
代替
a.mapValues(x => x.size)
Run Code Online (Sandbox Code Playgroud)
但我不能这样做
a.groupBy(_)
Run Code Online (Sandbox Code Playgroud)
代替
a.groupBy(x => x)
Run Code Online (Sandbox Code Playgroud)
par*_*tic 42
编写时a.groupBy(_)
,编译器将其理解为匿名函数:
x => a.groupBy(x)
Run Code Online (Sandbox Code Playgroud)
根据Scala规范§6.23,表达式中的下划线占位符将替换为匿名参数.所以:
_ + 1
扩大到 x => x + 1
f(_)
扩大到 x => f(x)
_
不会自行扩展(占位符不是任何表达式的一部分).该表达式x => a.groupBy(x)
会混淆编译器,因为它无法推断出类型x
.如果a
是某些类型E
元素的集合,那么编译器期望x
是类型的函数(E) => K
,但是K
无法推断类型...
Dan*_*ral 16
在这里看到它并不容易:
a.groupBy(_)
Run Code Online (Sandbox Code Playgroud)
但是更容易看到这样的事情:
a.mkString("<", _, ">")
Run Code Online (Sandbox Code Playgroud)
我正在部分应用方法/功能.我将它应用于一些参数(第一个和最后一个),并保留第二个参数未应用,所以我得到一个像这样的新函数:
x => a.mkString("<", x, ">")
Run Code Online (Sandbox Code Playgroud)
第一个示例只是一个特殊情况,其中部分应用了唯一参数.但是,在表达式上使用下划线时,它代表匿名函数中的位置参数.
a.mapValues(_.size)
a.mapValues(x => x.size)
Run Code Online (Sandbox Code Playgroud)
很容易混淆,因为它们都会导致匿名功能.实际上,还有第三个下划线用于将方法转换为方法值(也是一个匿名函数),例如:
a.groupBy _
Run Code Online (Sandbox Code Playgroud)