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でのコンストラクターのオーバーロードを理解している限り、私は適切な構文と、toの呼び出しが他の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問題が解決する可能性があります。ただし、それが...Tのサブクラスである可能性は少し低いようです。Int

  • 常に true である場合はT : Int、ジェネリックを削除しTます。

  • If Tis をジェネリックで無制限のままにしておくと、 when の特別なケースが残りますT : Int。セニアのソリューションはそれに適しています。

于 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 に答える