在Scala中如何使用多参数或序列构造函数?

3
这里是一个基本示例...我无法让Scala识别我想要以两种不同的方式初始化我的类:通过现有序列,或使用多个参数。
我收到的错误是:
"double definition: method apply:(params: Int*)chorle.scala.tests.MultiParam and method apply:(pList:
Seq[Int])chorle.scala.tests.MultiParam at line 9 have same type after erasure: (params: Seq)chorle.scala.tests.MultiParam"
好吧,我知道这里发生了什么-在编译后,这两个函数都会产生相同的头签名。然而,在实践中,它们的工作方式并不相同-如果我只有apply(Seq)版本,则无法调用:apply(1,2,3);反之亦然。我知道有各种方法可以修补实际的函数调用,但是如何在类中适当且仅一次地解决此问题?谢谢!
class MultiParam protected (pList:Seq[Int]) 

object MultiParam {
  def apply(pList:Seq[Int]): MultiParam = new MultiParam(pList)
  def apply(params: Int *): MultiParam = new MultiParam(params)


} 
2个回答

5
问题在于所谓的“重复参数”表单是一种语法糖,无论是在定义站点还是调用站点,它都是针对一种特殊的IndexedSeq。这导致了歧义。
标准集合库中有一种常见的处理方法,您可以在各个地方找到它:
package rrs.scribble

object MP {
  class MultiParam protected (pList:Seq[Int]) {
    override def toString: String = pList.mkString("[[", ", ", "]]")
  }

  object MultiParam {
    def apply(): MultiParam = new MP.MultiParam(List.empty[Int])
    def apply(ints: Seq[Int]): MultiParam = new MP.MultiParam(ints)
    def apply(i1: Int, iMore: Int*): MultiParam = new MP.MultiParam(i1 +: iMore)
  }
}

在REPL中:

scala> MultiParam()
res0: rrs.scribble.MP.MultiParam = [[]]

scala> MultiParam(12)
res3: rrs.scribble.MP.MultiParam = [[12]]

scala> MultiParam(12, 34)
res4: rrs.scribble.MP.MultiParam = [[12, 34]]

scala> MultiParam(12, 34, 56)
res5: rrs.scribble.MP.MultiParam = [[12, 34, 56]]

4

这些代码不能直接使用,因为没有办法同时生成两种方法。唯一的解决方法是将它们区分开来:

object MultiParam {
  def apply(pList:Seq[Int]): MultiParam = new MultiParam(pList)
  def apply(param: Int, params: Int *): MultiParam = new MultiParam(param +: params)
  def apply(): MultiParam = new MultiParam(Nil)
} 

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