重载泛型scala类中的构造函数

时间:2012-08-24 15:55:34

标签: scala generics

我正在尝试重载一个通用scala类中的构造函数,但它没有编译。

这是我的代码:

class V[T](m: Map[T,Double]) {
    def this(dt: Seq[Double]) = this(dt.zipWithIndex.map(_.swap).toMap)
}

我得到的错误消息:

ERROR: called constructor's definition must precede calling constructor's definition : line 6

ERROR: overloaded method constructor V with alternatives:   
(dt: Seq[Double])V[T] <and>   (m: Map[T,Double])V[T]  cannot be applied to 
(scala.collection.immutable.Map[Int,Double]) : line 6

据我所知,scala中的构造函数重载,我认为我遵循了正确的语法和对this的调用应该优先于其他所有内容的限制。

那么我做错了什么以及如何解决这个问题呢?

2 个答案:

答案 0 :(得分:3)

使用

def this(dt: Seq[Double]) = this(dt.zipWithIndex.map(_.swap).toMap)
  • 您正在制作新地图Map[Int,Double]; Int是由zipWithIndex创建的索引的类型。

  • 如果TInt,那么您可以使用构造函数(m:Map[T,Double]

  • 但是:由于您正在定义类,因此T尚未绑定到某个类型。此时类型匹配也不会将T绑定到Int

  • 因此类型匹配失败。

解决方案:

如何解决这个问题取决于你想要做什么。

  • 如果是T <: Int的情况,那么将类型参数与<: Int绑定可以解决您的问题;但是TInt的子类似乎不太可能......

  • 如果T : Int始终为真,则删除通用T

  • 如果T要保持通用且无界限,则会让您在T : Int时做出特殊情况; senia的解决方案看起来很不错。

答案 1 :(得分:0)

您可以使用随播对象修复它:

scala> :paste
// Entering paste mode (ctrl-D to finish)

class V[T](m: Map[T,Double])

object V{
  def apply(dt: Seq[Double]) = new V[Int](dt.zipWithIndex.map(_.swap)(collection.breakOut))
}

// Exiting paste mode, now interpreting.

defined class V
defined module V

scala> V(Seq(1.,2.,3.))
res0: V[Int] = V@1130e2ea