从Scala中的seq到_ *

时间:2015-02-14 16:12:06

标签: scala variadic-functions

有谁知道我们如何以自动方式从任何Seq转换为_ *?每次我们有Seq时强制类型并且方法使用类型为vararg的参数非常麻烦。

def mean[T: Numeric](elems: T*): Double
...
elems = Seq(1.0, 2.0, 3.0)
mean(elems) // this doesn't compiles
mean(elems: _*) // this compiles but it is cumbersome

2 个答案:

答案 0 :(得分:6)

这是唯一的方法。这就是为什么varargs最好只用在库的公共接口上的原因,即便如此,特别是当你认为调用者将使用字面指定的元素而不是集合进行调用时。如果一个方法很可能会在一个集合参数上被调用,那么varargs可以适应你的目标,即减少语法噪音,正如你所注意到的那样。

答案 1 :(得分:3)

如果方法不是通用的,则可以添加重载:

def mean(elems: Seq[Double]): Double = ...
def mean(elems: Double*)(implicit d: DummyImplicit): Double = mean(elems)

唉,在这种情况下它不起作用:

scala> object X { def f[T: Numeric](x: T*) = x; def f[T: Numeric](x: Seq[T])(implicit d: DummyImplicit) = x }
defined module X

scala> X.f(Seq(1, 2))
<console>:9: error: ambiguous reference to overloaded definition, both method f in object X of type [T](x: Seq[T])(implicit evidence$2: Numeric[T], implicit d: DummyImplicit)Seq[T] and  method f in object X of type [T](x: T*)(implicit evidence$1: Numeric[T])Seq[T] match argument types (Seq[Int])
              X.f(Seq(1, 2))
                ^

因为编译器认为T可以是IntSeq[Int],并且在检查implicits是否可用于两者之前停止(至少在Scala 2.10中)。