scala splat 可以用于任何不是可变参数的东西吗?

Posted

技术标签:

【中文标题】scala splat 可以用于任何不是可变参数的东西吗?【英文标题】:Can scala splat be used for anything that isn't a varargs? 【发布时间】:2011-08-04 16:46:59 【问题描述】:

例如:

scala> def pipes(strings:String*) = strings.toList.mkString("|")

我可以正常调用:

scala> pipes("foo", "bar")
res1: String = foo|bar

或者用splat:

scala> val args = List("a","b","c")
scala> pipes(args:_*)
res2: String = a|b|c

但是我可以使用 splat 为除 varargs 参数之外的任何参数提供参数吗?例如,我想做类似的事情:

scala> def pipeItAfterIncrementing(i:Int, s:String) = (i + 1) + "|" + s
scala> val args:Tuple2[Int, String] = (1, "two")
scala> pipeItAfterIncrementing(args:_*)

这不起作用,但是有没有什么方法可以实现从单个对象提供多个参数的相同效果,无论是元组还是其他对象?鉴于元组的长度和类型在编译时都是已知的,是否有任何理由无法为元组实现这一点?

【问题讨论】:

【参考方案1】:

您可以使用Function.tupled 来做到这一点:将一个接受 n 个参数的函数转换成一个接受单个元组参数的函数 n。正如所料,Function.untupled 执行相反的工作。

特殊类型归属: _* 仅适用于重复参数(a.k.a. varargs)。

scala> def pipeItAfterIncrementing(i:Int, s:String) = (i + 1) + "|" + s
pipeItAfterIncrementing: (i: Int,s: String)java.lang.String

scala> def tupledPipeItAfterIncrementing = Function.tupled(pipeItAfterIncrementing _)
tupledPipeItAfterIncrementing: ((Int, String)) => java.lang.String

scala> val args:Tuple2[Int, String] = (1, "two")
args: (Int, String) = (1,two)

scala> tupledPipeItAfterIncrementing(args)
res0: java.lang.String = 2|two

【讨论】:

【参考方案2】:

好吧……

scala> def pipeItAfterIncrementing(i:Int, s:String) = (i + 1) + "|" + s
scala> val args:Tuple2[Int, String] = (1, "two")
scala> (pipeItAfterIncrementing _).tupled(args)

会给你想要的2|two

【讨论】:

您可以(并鼓励)为多个答案投票。只是“接受”被简化为一个答案。 另外,您的回答还表明tupled 也是Function 实例上的一种方法,除了Function 对象上的方法。 @JPP,当我发布我的后看到它时,那个和你的还没有示例;-) @subsub 对,我正在同时编辑它……看起来前几分钟很忙:)

以上是关于scala splat 可以用于任何不是可变参数的东西吗?的主要内容,如果未能解决你的问题,请参考以下文章

Scala 可变长参数

在 Scala 中使用啥类型来存储内存中的可变数据表?

Scala函数使用可变参数

用 YARD 记录“splatted”参数的最佳方法是啥? [关闭]

Scala可变参数列表,命名参数和参数缺省

我怎样才能将双 splat 论点折叠成虚无?