在Scala中的参数列表中是否会直接支持元组解包?

时间:2011-06-19 00:40:19

标签: scala parameters tuples iterable-unpacking

在Haskell中你可以写:

x :: (Int,Int) -> Int
x (p,s) = p

在Scala中你会写:

def x(a: (Int, Int)) = a._1

或:

def x(a: (Int, Int)) = a match {
    case (p, s) => p
}

为什么不喜欢

def x(_: (p: Int, s: Int)) = p

def x(foo: (p @ Int, s @ Int)) = p

4 个答案:

答案 0 :(得分:11)

您正在寻找的功能称为 destructuring ,并且以其一般形式,将远远超出元组解包。我经常发现自己希望Scala拥有它,因为它是模式匹配语法的自然扩展:

def first((f: Int, l: Int)) = f
def displayName(Person(first, last)) = last + ", " + first

解构 (有点)以变量/值定义的形式出现:

val (f, l) = tuple
val Person(first, last) = person

不幸的是,围绕此类定义存在一些type safety issues,我认为您很快就会在参数列表中看到解构。

答案 1 :(得分:4)

您可以创建一个函数来接收与元组类型相对应的参数列表,将Function.tupled应用于该函数,然后应用元组:

scala> def fun(x:Int,y:Int)=x+y
fun: (x: Int,y: Int)Int

scala> val tuple = (1,2)
tuple: (Int, Int) = (1,2)

scala> Function.tupled(fun _)(tuple)
res9: Int = 3

通过这种方式,您可以为问题实现有效的解决方法

答案 2 :(得分:2)

这称为多次调度,JVM不支持它。尽管如此,Scala 可以重写一个方法来使显式匹配变得不必要,但它不是优先考虑的事情 - 或者据我所知,甚至是计划的 - 这样做。

有趣的是,从某种意义上说,它支持功能,限制所有变体必须一起出现。例如:

def x: ((Int, Int)) => Int = {
    case (p, _) => p
}

答案 3 :(得分:0)

另一种方法是使参数列表和元组在语言中使用相同的东西。