使用重复参数的成本

Pal*_*ndo 5 scala variadic-functions argument-passing scala-2.8

我考虑重构一些目前采用类型参数ListSet具体类参数的方法签名List[Foo]- 使用重复参数代替:Foo*.

更新:以下推理存在缺陷,请继续...
这将允许我使用相同的方法名称并根据参数类型重载它.这是不可能的使用List或者Set,因为List[Foo]List[Bar]擦除之后具有相同类型:List[Object].

在我的情况下,重构的方法与scala.Seq[Foo]重复参数的结果一起工作正常.我将不得不更改所有调用并将序列参数类型注释添加到所有集合参数:baz.doStuffWith(foos:_*).

鉴于从集合参数切换到重复参数在语义上是等效的,这个更改是否会产生一些我应该注意的性能影响?

scala 2.7._和2.8的答案是否相同?

Dan*_*ral 4

当 Scala 调用 Scala varargs 方法时,该方法将接收一个扩展的对象Seq。当使用 进行调用时: _*,对象将按原样*传递,而不进行复制。以下是这方面的示例:

scala> object T {
     |   class X(val self: List[Int]) extends SeqProxy[Int]  {
     |     private val serial = X.newSerial
     |     override def toString = serial.toString+":"+super.toString
     |   }
     |   object X {
     |     def apply(l: List[Int]) = new X(l)
     |     private var serial = 0
     |     def newSerial = {
     |       serial += 1
     |       serial
     |     }
     |   }
     | }
defined module T

scala> new T.X(List(1,2,3))
res0: T.X = 1:List(1, 2, 3)

scala> new T.X(List(1,2,3))
res1: T.X = 2:List(1, 2, 3)

scala> def f(xs: Int*) = xs.toString
f: (Int*)String

scala> f(res0: _*)
res3: String = 1:List(1, 2, 3)

scala> f(res1: _*)
res4: String = 2:List(1, 2, 3)

scala> def f(xs: Int*): Seq[Int] = xs
f: (Int*)Seq[Int]

scala> def f(xs: Int*) = xs match {
     |   case ys: List[_] => println("List")
     |   case _ => println("Something else")
     | }
f: (Int*)Unit

scala> f(List(1,2,3): _*)
List

scala> f(res0: _*)
Something else

scala> import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.ArrayBuffer

scala> def f(xs: Int*) = xs match {
     |   case ys: List[_] => println("List")
     |   case zs: ArrayBuffer[_] => zs.asInstanceOf[ArrayBuffer[Int]] += 4; println("Array Buffer")
     |   case _ => println("Something else")
     | }
f: (Int*)Unit

scala> val ab = new ArrayBuffer[Int]()
ab: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()

scala> ab + 1
res11: scala.collection.mutable.Buffer[Int] = ArrayBuffer(1)

scala> ab + 2
res12: scala.collection.mutable.Buffer[Int] = ArrayBuffer(1, 2)

scala> ab + 3
res13: scala.collection.mutable.Buffer[Int] = ArrayBuffer(1, 2, 3)

scala> f(ab: _*)
Array Buffer

scala> ab
res15: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4)
Run Code Online (Sandbox Code Playgroud)

笔记

  • AnArray作为 a 传递WrappedArray。然而,不涉及任何元素的复制,并且对WrappedArraywill 的更改会反映在Array.