我有一个案例类,将Seq [T]作为参数:
case class MyClass(value: Seq[T])
我现在希望能够写
MyClass(t1,t2,t3)
所以我定义了
object MyClass {
def apply(value: T*) = new MyClass(value.toSeq)
}
它不起作用,因为案例类定义了
object MyClass {
def apply(value: Seq[T])
}
擦除后,和Seq [T]和T *具有相同的类型,因此我不能超载它们。
但我想允许两种访问方式。应该允许这两种方式:
MyClass(t1,t2,t3)
MyClass(some_seq_of_T)
由于Seq [T]和T *几乎是相同的类型(至少在擦除之后;并且在具有参数T *的函数内部变为Seq [T]),我认为应该有一种方法允许两种方式叫它。
有吗?
答案 0 :(得分:6)
你可以作弊并定义你的同伴:
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]
答案 1 :(得分:3)
这是没有案例类的解决方案:
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
答案 2 :(得分:0)
不能有两个同名的方法,其中一个方法采用Seq[T]
类型的参数,一个采用T*
。编译器如何知道是否像
val s = Seq(1,2,3)
foo(s)
应该调用第一个方法或第二个方法(使用T = Int)或第二个方法(使用T = Seq [Int])?