3

这是基本示例。我无法让 scala 认识到我希望能够以两种不同的方式初始化我的类:通过现有序列或使用多个参数。

我收到的错误是:

双重定义:第 9 行的方法 apply:(params: Int*)chorle.scala.tests.MultiParam 和方法 apply:(pList:
Seq[Int])chorle.scala.tests.MultiParam 在擦除后具有相同的类型:(params:序列)chorle.scala.tests.MultiParam

好的,我知道这里发生了什么 - 编译后两个函数都会产生相同的标头签名。但是,实际上它们的工作方式不同 - 如果我只有 apply(Seq) 版本,我无法调用:apply(1,2,3) ......而且我无法调用 apply(seq)其他方式。我知道可以修补实际函数调用的各种方法,但是如何正确解决这个问题并且只在课堂上解决一次?谢谢!

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)


} 
4

2 回答 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]]
于 2013-02-05T03:14:15.397 回答
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)
} 
于 2013-02-05T03:08:37.707 回答