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)
}
source to share
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)
}
source to share
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]]
source to share