0

这对我来说似乎不合逻辑:

scala> val a = Map((1, "111"), (2, "222"))
a: scala.collection.immutable.Map[Int,String] = Map(1 -> 111, 2 -> 222)

scala> val b = a.map((key, value) => value)
<console>:8: error: wrong number of parameters; expected = 1
       val b = a.map((key, value) => value)
                                  ^
scala> val c = a.map(x => x._2)
c: scala.collection.immutable.Iterable[String] = List(111, 222)

我知道我可以说val d = a.map({ case(key, value) => value })

但是为什么不能说呢 a.map((key, value) => value)?只有一个类型为Tuple2[Int, String]or的参数Pair of Int, Stringa.map((key, value) => value)和有什么区别a.map(x => x._2)

更新

val myTuple2 = (1, 2)-- 这是一个变量,对吗?

for ( (k, v) <- a ) yield v--(k, v)也只有一个变量,对吗?

map((key, value) => value)-- 2 个变量。奇怪的。

那么如何在不使用的情况下指定类型Tuple2(或任何其他类型)的变量?mapcase

更新2:

那有什么问题?

Map((1, "111"), (2, "222")).map( ((x,y):Tuple2[Int, String]) => y)- 错误的

Map((1, "111"), (2, "222")).map( ((x):Tuple2[Int, String]) => x._2)- 行

4

3 回答 3

6

好吧,你还是不信。在这种情况下,回退到真相的来源(嗯,有点)是非常合理的:神圣规范(又名,Scala 语言规范)。

在此处输入图像描述

因此,在匿名函数中,参数是单独处理的,而不是作为一个完整的元组带(而且它非常聪明,否则,您将如何调用具有 2、... n 个参数的匿名函数?)。

同时

val x = (1, 2) 

是 Tiple2[Int,Int] 类型的单个项目(如果您有兴趣,也可以找到相应的规范部分)。

for ( (k, v) <- a ) yield v

在这种情况下,您将一个变量解压缩为两个变量。它类似于

val x = (1, 2) // one variable -- tuple
val (y,z) = x  // two integer variables unpacked from one

有些人称之为解构赋值,这是模式匹配的一个特例。你已经提供了另一个模式匹配的例子:

a.map({ case(key, value) => value })

我们可以将其解读为map 接受由部分函数字面量生成的函数,从而可以使用模式匹配

于 2013-07-01T15:15:44.597 回答
2

你基本上是在问同样的问题:

Scala - lambda参数可以匹配元组吗?

您已经列出了他们在那里列出的大部分选项,包括使用 PartialFunction 的公认答案。

但是,由于您在map函数中使用 lambda,因此您可以改用for推导式:

for ( (k, v) <- a ) yield v

或者,您可以使用该Function2.tupled方法来修复您的 lambda 类型:

scala> val a = Map((1, "111"), (2, "222"))
a: scala.collection.immutable.Map[Int,String] = Map(1 -> 111, 2 -> 222)
scala> a.map( ((k:Int,v:String) => v).tupled )
res1: scala.collection.immutable.Iterable[String] = List(111, 222)

要使用上面的 om-nom-nom 在您的线程中回答您的问题,请查看以下输出:

scala> ( (x:Int,y:String) => y ).getClass.getSuperclass
res0: Class[?0] forSome { type ?0 >: ?0; type ?0 <: (Int, String) => String } = class scala.runtime.AbstractFunction2

请注意,匿名函数的超类(x:Int,y:String) => yFunction2[Int, String, String],不是Function1[(Int, String), String]

于 2013-07-01T15:01:10.427 回答
-2

您可以使用模式匹配(或部分函数,​​在这种情况下是相同的),注意尖括号:

val b = a.map{ case (key, value) => value }
于 2013-07-01T15:03:34.360 回答