为什么在函数args中使用case更好地在map函数中进行模式匹配

时间:2015-06-12 17:21:51

标签: scala

Scala cheatsheet对"函数args中的用例进行模式匹配。"就这样

GOOD (xs zip ys) map { case (x,y) => x*y }
BAD (xs zip ys) map( (x,y) => x*y )

为什么前者更好?

3 个答案:

答案 0 :(得分:5)

(x, y) => x * y是以下的语法糖(我假设我们在讨论整数):

new Function2[Int, Int, Int] {
  def apply(x: Int, y: Int): Int = x * y
}
集合上的

map需要一个A => B(去掉Function1[A, B]),这与Function2完全不同。因此,在您的示例中不使用后一版本的一个很好的理由是编译器不会接受它。

如果您的方法实际需要Function2,则可以使用以下任一方法:

scala> val pair = (List(1, 2, 3), List(4, 5, 6))
pair: (List[Int], List[Int]) = (List(1, 2, 3),List(4, 5, 6))

scala> pair.zipped.map { (x, y) => x * y }
res0: List[Int] = List(4, 10, 18)

scala> pair.zipped.map { case (x, y) => x * y }
res1: List[Int] = List(4, 10, 18)

case版本的工作原理是因为编译器支持Function2的函数文字语法中的模式匹配。一般来说,我个人更喜欢(x, y) => x * y语法,当它工作时(即,当你的方法需要Function2并且你不需要做任何其他模式匹配时)

答案 1 :(得分:1)

嗯,后者根本行不通。

scala> val xs = List(1, 2, 3)
xs: List[Int] = List(1, 2, 3)

scala> val ys = List(4, 5, 6)
ys: List[Int] = List(4, 5, 6)

scala> (xs zip ys).map((x,y) => x*y)
<console>:10: error: missing parameter type
Note: The expected type requires a one-argument function accepting a 2-Tuple.
      Consider a pattern matching anonymous function, `{ case (x, y) =>  ... }`
              (xs zip ys).map((x,y) => x*y)
                               ^
<console>:10: error: missing parameter type
              (xs zip ys).map((x,y) => x*y)
                                 ^

scala> (xs zip ys).map { case (x,y) => x*y }
res0: List[Int] = List(4, 10, 18)

作为替代

import Function.tupled
(xs zip ys) map tupled { (x,y) => x*y }

答案 2 :(得分:-1)

使用模式匹配,您显式指定要映射的输入参数的形式(类型)(接受元组-2的单参数函数);在第二种情况下(没有模式匹配),您需要显式指定类型(因为它具有与2参数函数相同的形式)。你可以通过在REPL(scala 2.11.6)中输入它来看到这一点:

scala> val xs = List(1,2,3,4)
xs: List[Int] = List(1, 2, 3, 4)
scala> val ys = List(1,2,3,4)
ys: List[Int] = List(1, 2, 3, 4)
scala> (xs zip ys) map { case (x,y) => x*y }
res0: List[Int] = List(1, 4, 9, 16)
scala> (xs zip ys) map ((x,y) => x*y)
<console>:10: error: missing parameter type
Note: The expected type requires a one-argument function accepting
a 2-Tuple.
Consider a pattern matching anonymous function, `{ case (x, y) =>  }`
          (xs zip ys) map ((x,y) => x*y)
                            ^
<console>:10: error: missing parameter type
          (xs zip ys) map ((x,y) => x*y)