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