分解函数参数中的元组

72

在Python中,我可以这样做:

def f((a, b)):
    return a + b

d = (1, 2)
f(d)

这里传入的元组在传递给f函数时被分解了。

目前在Scala中我正在做这个:

def f(ab: (Int, Int)): Int = {
    val (a, b) = ab
    a + b
}

val d = (1, 2)
f(d)

有没有什么办法可以让分解在传递参数时发生?只是好奇。


6
有趣。我不知道在Python中这甚至是可能的。 - Debilski
1
另外:https://issues.scala-lang.org/browse/SI-813 - Debilski
3个回答

98
您可以创建一个函数并使用模式匹配来匹配其输入:
scala> val f: ((Int, Int)) => Int = { case (a,b) => a+b }
f: ((Int, Int)) => Int

scala> f(1, 2)
res0: Int = 3

或者使用 match 关键字匹配方法的输入:

scala> def f(ab: (Int, Int)): Int = ab match { case (a,b) => a+b }
f: (ab: (Int, Int))Int

scala> f(1, 2)
res1: Int = 3

另一种方法是使用带有两个参数的函数并将其“元组化”:

scala> val f: (Int, Int) => Int = _+_
f: (Int, Int) => Int = <function2>

scala> val g = f.tupled // or Function.tupled(f)
g: ((Int, Int)) => Int = <function1>

scala> g(1, 2)
res10: Int = 3

// or with a method
scala> def f(a: Int, b: Int): Int = a+b
f: (a: Int, b: Int)Int

scala> val g = (f _).tupled // or Function.tupled(f _)
g: ((Int, Int)) => Int = <function1>

scala> g(1, 2)
res11: Int = 3

// or inlined
scala> val f: ((Int,Int)) => Int = Function.tupled(_+_)
f: ((Int, Int)) => Int = <function1>

scala> f(1, 2)
res12: Int = 3

8

Scala 3 开始,通过改进的 tupled函数 特性:

// val tuple = (1, 2)
// def f(a: Int, b: Int): Int = a + b
f.tupled(tuple)
// 3

Scastie上玩耍吧。


-2
object RandomExperiments extends App{
  def takeTuple(t:(Int,Int))=print (s"$t ${t._1}\n")
  takeTuple(1,3)
  takeTuple((1,3))
  takeTuple(((1,3)))

}

输出:

(1,3) 1
(1,3) 1
(1,3) 1

2
这基本上与Brian Agnews的回答相同。但也许那只是个愚人节玩笑? - Daniel Warmuth
第一个能够工作是因为在Scala中可以使用没有括号的语法。它并不是使用两个参数调用takeTuple,而是使用一个元组参数调用takeTuple,而不需要用括号将参数包装起来(这实际上是在#2中完成的)。 - boggy
我不知道你在这里尝试回答什么。 - IamDOM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接