Scala splat运算符仅用于参数列表的一部分



Python 3将允许可迭代的解包,例如:

>>> def foo(a, b, c): return a + b + c
... 
>>> s1 = "one"
>>> s2 = ("two", "three")
>>> foo(s1, *s2)
'onetwothree'

我看过如何将函数应用于元组?和scala-tuple解包,但我在scala(2.13(中模拟它时遇到了问题:

scala> def foo(a: String, b: String, c: String): String = a + b + c
foo: (a: String, b: String, c: String)String
scala> val s1 = "one"
s1: String = one
scala> val s2 = Seq("two", "three")
s2: Seq[String] = List(two, three)

如何模拟foo(s1, s2: _*)

我得到的最接近的是uncurried/curried的组合,但坦率地说,我真的不明白为什么最后一次尝试不起作用:

scala> Function.uncurried((foo _).curried(s1))
res17: (String, String) => String = scala.Function$$$Lambda$897/0x0000000801070840@145f1f97
scala> Function.uncurried((foo _).curried(s1))(s2(0), s2(1))
res19: String = onetwothree
scala> Function.uncurried((foo _).curried(s1))(s2: _*)
^
error: not enough arguments for method apply: (v1: String, v2: String)String in trait Function2.
Unspecified value parameter v2.

如果s2是一个元组,那么事情就很简单了。

def foo(a:String, b:String, c:String) :String = a + b + c
val s1 = "one"
val s2 = ("two", "three")
(foo(s1, _, _)).tupled(s2)  //res0: String = onetwothree

但作为一个Seq(),我认为你能做的最好的事情就是使用一个包装器来为你打开元素的包装。

def foox(ss:String*) :String = foo(ss(0), ss(1), ss(2))  //danger
val s3 = Seq("two", "three")
foox(s1 +: s3 :_*)  //res1: String = onetwothree

没有简单的方法(据我所知(可以将非varargs方法转换为varargs的方法/函数。

最新更新