Constructors with multiple parameters or sequences in Scala?

here is a basic example .. I can't get scala to find out that I want the ability to initialize my class in two different ways: via an existing sequence or using multiple parameters.

Received error:

double definition: method is applied: (params: Int *) chorle.scala.tests.MultiParam and method is applied: (pList:
Seq [Int]) chorle.scala.tests.MultiParam on line 9 are of the same type after erasure: (params : Seq) chorle.scala.tests.MultiParam

Which, I understand what's going on here - after compilation, both functions result in the same header signature. However, in practice they don't work the same way - I cannot declare: apply (1,2,3) if I only have the application version (Seq) ... and I cannot declare the application (seq) another way around. I know of various ways that I could fix the actual function call, but how can I refer to this correctly and only once per class? Thank!

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)


} 

      

+3


source to share


2 answers


Well, they cannot be used because there is no way to generate both methods. The only way to get around this is to eliminate them:



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)
} 

      

+4


source


The problem arises because the form of so-called "repeating parameters" is syntactic sugar, both in the definition site and in the invocation site for the particular type IndexedSeq

, which leads to ambiguity.

There is a way to deal with this here, which you can find in various places in the standard collection library:

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)
  }
}

      



In the 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]]

      

+5


source







All Articles