首页 文章

Scala:重载(Seq [T])和(T *)

提问于
浏览
5

我有一个案例类,以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]),我认为应该有一种方法允许两种方式调用它 .

在那儿?

3 回答

  • 0

    你可以欺骗一点,然后像这样定义你的同伴:

    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]

  • 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
    
  • 6

    不能有两个同名的方法,其中一个采用 Seq[T] 类型的参数,一个采用 T* . 编译器如何知道调用是否像

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

    应该调用第一种方法或第二种方法(使用T = Int)或第二种方法(使用T = Seq [Int])?

相关问题