与映射操作中的元组解包有关,我不明白为什么我们需要一个case
(对我来说看起来像一个部分函数(来从元组中提取值,如下所示:
arrayOfTuples map {case (e1, e2) => e1.toString + e2}
而不是以与foldLeft
相同的方式提取,例如
def sum(list: List[Int]): Int = list.foldLeft(0)((r,c) => r+c)
无论如何,在第一种情况下我们不指定参数的类型,那么为什么我们需要 case
语句呢?
因为在 Scala 函数中,参数列表和元组不像在 Haskell 和其他函数式语言中那样是一个统一的概念。所以一个函数:
(t: (Int, Int)) => ...
与函数不同:
(e1: Int, e2: Int) => ...
在第一种情况下,您可以使用模式匹配来提取元组元素,这始终使用case
语法来完成。实际上,表达式:
{case (e1, e2) => ...}
是以下的简写:
t => t match {case (e1, e2) => ...}
已经有一些关于统一元组和函数参数列表的讨论,但是关于Java重载规则以及默认/命名参数也存在复杂性。所以,我认为这些概念不太可能在Scala中统一起来。
具有一个原始参数的 Lambda
跟
var listOfInt=(1 to 100).toList
listOfInt.foldRight(0)((current,acc)=>current+acc)
您有一个对两个参数进行操作的 lambda 函数。
具有一个元组类型参数的 Lambda
跟
var listOfTuple=List((1,"a"),(2,"b"),(3," "))
listOfTuple.map(x => x._1.toString + x._2.toString)
您有一个 lambda 函数处理一个参数(类型 Tuple2[Int, String]
(
两者都适用于类型推断。
具有一个参数的部分 lambda
跟
listOfTuple.map{case (x,y) => x.toString + y.toString}
您有一个 lambda 函数,使用一个参数(类型 Tuple2[Int, String]
(。然后,此 lambda 函数在内部使用 Tuple2.unapply
将一个参数分解为多个值。这仍然适用于类型推断。该case
是分解("模式匹配"(值所必需的。
此示例有点不直观,因为 unapply 返回一个元组作为其结果。在这种特殊情况下,可能确实有一个技巧,所以 Scala 直接使用提供的元组。但我真的不知道有这样的伎俩。
更新:带有柯里奇的 Lambda 函数
确实有一个技巧。跟
import Function.tupled
listOfTuple map tupled{(x,y) => x.toString + y.toString}
您可以直接使用元组。但当然,这确实是一个技巧:你提供一个对两个参数而不是元组进行操作的函数。 然后,tupled
获取该函数并将其更改为其他函数,对元组进行操作。这种技术也称为取消卷曲。
备注:
当y
已经是字符串时,y.toString
是多余的。这不被认为是好的风格。为了举例,我把它留了下来。您应该在实际代码中省略它。