映射Pair类型的变量 - 不可能

时间:2013-07-01 14:53:17

标签: scala

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

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]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的情况下在map中指定case(或任何其他类型)的变量?

UPDATE2:

这有什么问题?

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

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

3 个答案:

答案 0 :(得分:6)

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

enter image description here

因此,在匿名函数中,参数是单独处理的,而不是整个元组带(并且它非常聪明,否则,如何用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接受由部分函数文字生成的函数,它允许使用模式匹配

答案 1 :(得分:2)

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

Scala - can a lambda parameter match a tuple?

您已经列出了他们在那里列出的大多数选项,包括使用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) => y的超类是Function2[Int, String, String],而不是Function1[(Int, String), String]

答案 2 :(得分:-2)

你可以使用模式匹配(或部分功能,在这个例子中这是相同的),注意尖括号:

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