Scala: overload (Seq [T]) and (T *)

I have a case class that takes Seq [T] as a parameter:

case class MyClass(value: Seq[T])

Now i want to write

MyClass(t1,t2,t3)

So I defined

object MyClass {
    def apply(value: T*) = new MyClass(value.toSeq)
}

This does not work because the case class defines

object MyClass {
    def apply(value: Seq[T])
}

and Seq [T] and T * are of the same type after erasing, so I cannot overload them.

But I would like to allow both access paths. Both paths must be allowed:

MyClass(t1,t2,t3)
MyClass(some_seq_of_T)

Since Seq [T] and T * are almost of the same type (at least after erasing, and inside the function with the parameter T *, it becomes Seq [T]), I think there should be a way to resolve both ways of calling it.

Whether there is a?

+5
source share
3 answers

You can trick a little and define your partner as follows:

case class MyClass[T](value: Seq[T])

object MyClass {
  def apply[T](first: T, theRest: T*) = new MyClass(first :: theRest.toList)
  def apply[T]() = new MyClass[T](Nil)
}

apply MyClass(1,2,3), . Scond apply 0 . .

MyClass(Seq(1,2,3)), MyClass(1,2,3) MyClass(). , , , MyClass[Nothing]

+6

case:

scala> class A[T] (ts: Seq[T]) { def this(ts: T*)(implicit m: Manifest[T]) = this(ts) }
defined class A

scala> new A(1)
res0: A[Int] = A@2ce62a39

scala> new A(Seq(1))
res1: A[Seq[Int]] = A@68634baf
+3

You cannot use two methods of the same name, where a type parameter is taken Seq[T], and one accepts T*. How does the compiler know if the call will be like

val s = Seq(1,2,3) 
foo(s)

Is it supposed to call the first method or the second method (with T = Int) or the second (with T = Seq [Int])?

0
source

All Articles