这对我来说似乎不符合逻辑:
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, String
。 a.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)
- 确定
答案 0 :(得分: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接受由部分函数文字生成的函数,它允许使用模式匹配。
答案 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 }