为什么其中一个拆分和过滤器工作而不是另一个?

Sum*_*Pal 1 scala filter

val c = s.split(" ").filter(_.startsWith("#")).filter(x =>  
  x.contains("worcester") || x.contains("energy"))
Run Code Online (Sandbox Code Playgroud)

作品

但事实并非如此

val c = s.split(" ").filter(_.startsWith("#")).filter(_.contains("worcester") || 
  _.contains("energy"))
Run Code Online (Sandbox Code Playgroud)

我没有清楚地理解为什么后者不起作用 - 可能是我的基础知识存在缺陷

任何帮助将非常感谢Sumit

Ben*_*ich 5

像这样使用下划线称为占位符语法.所以,类似的东西_.contains("x")相当于x => x.contains("x").使用占位符语法时,您只能使用每个参数一次.使用多个占位符表示匿名函数的多个参数(然后按下划线的顺序使用).所以,当你写:

o.filter(_.contains("worcester") || _.contains("energy"))
Run Code Online (Sandbox Code Playgroud)

理论上它相当于

o.filter((x, y) => x.contains("worcester") || y.contains("energy"))
Run Code Online (Sandbox Code Playgroud)

哪个不进行类型检查,因为filter需要一个类型的参数Array[String] => Boolean.

使用reduce变体时,多个占位符很常见.例如,可以将因子计算为(1 to n).reduce(_ * _).这是因为reduce期望一个类型的参数(Int, Int) => Int,因此_ * _,它等于(x, y) => x * y符合预期的类型.

值得注意的是,占位符语法适用于尽可能小的范围.因此,例如,f(g(_))相当于f(x => g(x)),而不是x => f(g(x)),这是一个常见的错误.

您可以在此处找到Scala中使用下划线的完整列表,以及有关此处占位符语法的更多信息.