Scala强调地图和过滤器的表示法

use*_*285 0 scala

说我有以下代码:

val a: List[(Int, String)] = List((1,"A"),(2,"B"),(3,"C"))
val b: List[String] = List("A","C","E")
Run Code Online (Sandbox Code Playgroud)

我可以:

a.map{case (fst,snd) => (fst,snd + "a")}
a.filter{case (_,snd) => b.contains(snd)}
Run Code Online (Sandbox Code Playgroud)

但为什么我不能这样做:

a.map((_._1,_._2 + "a"))
a.filter(b.contains(_._2))
Run Code Online (Sandbox Code Playgroud)

有没有办法用下划线表示法完成此操作,还是我被迫在这里?

Dan*_*ser 5

例如:

a.map((_._1,_._2 + "a"))
Run Code Online (Sandbox Code Playgroud)

每个占位符(即每个下划线/ _)在参数表达式中引入一个新参数.

引用Scala规范

表达式(语法类别Expr)可以_在标识符合法的位置包含嵌入的下划线符号.这样的表达式表示匿名函数,其中下划线的后续出现表示连续的参数.

[...]

左列中的匿名函数使用占位符语法.这些中的每一个都相当于其右侧的匿名函数.

|---------------------------|----------------------------|
|`_ + 1`                    | `x => x + 1`               |
|`_ * _`                    | `(x1, x2) => x1 * x2`      |
|`(_: Int) * 2`             | `(x: Int) => (x: Int) * 2` |
|`if (_) x else y`          | `z => if (z) x else y`     |
|`_.map(f)`                 | `x => x.map(f)`            |
|`_.map(_ + 1)`             | `x => x.map(y => y + 1)`   |
Run Code Online (Sandbox Code Playgroud)

当您需要多次使用给定参数时,您必须使用扩展表单.因此,您的示例必须重写为:

a.map(x => (x._1, x._2 + "a"))
Run Code Online (Sandbox Code Playgroud)

例如

a.filter(b.contains(_._2))
Run Code Online (Sandbox Code Playgroud)

问题是你实际上是在传递一个匿名函数contains而不是filter,所以你也不能在这里使用下划线表示法.相反,你必须写

a.filter(x => b.contains(x._2))
Run Code Online (Sandbox Code Playgroud)