我正在尝试重载一个通用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
的调用应该优先于其他所有内容的限制。
那么我做错了什么以及如何解决这个问题呢?
答案 0 :(得分:3)
使用
def this(dt: Seq[Double]) = this(dt.zipWithIndex.map(_.swap).toMap)
您正在制作新地图Map[Int,Double]
; Int
是由zipWithIndex
创建的索引的类型。
如果T
为Int
,那么您可以使用构造函数(m:Map[T,Double]
。
但是:由于您正在定义类,因此T尚未绑定到某个类型。此时类型匹配也不会将T
绑定到Int
。
因此类型匹配失败。
如何解决这个问题取决于你想要做什么。
如果是T <: Int
的情况,那么将类型参数与<: Int
绑定可以解决您的问题;但是T
是Int
的子类似乎不太可能......
如果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