2

我正在尝试在通用 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应该先于其他所有内容的限制。

那么我做错了什么,我该如何解决这个问题?

4

2 回答 2

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,那么将 type-param 与 绑定<: Int可以解决您的问题;但是,这似乎不太可能TInt...的子类

  • 如果它总是如此T : Int,那么放弃泛型T

  • 如果T要保持通用性和无界性,那么您就可以为 when 做一个特殊情况T : Int;senia 的解决方案看起来不错。

于 2012-08-24T16:29:34.150 回答
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
于 2012-08-24T16:22:43.640 回答