0

私は次のコードを持っています:

trait CellT[VAL <: AnyVal] {
  var value: VAL
  type NEXT <: AnyVal
  var next: CellT[NEXT]
}

abstract class Cell[VAL <: AnyVal] extends CellT[VAL] {
  var next = this  // defaults to `this`. ERROR
}

// impl example:
class CellInt extends Cell[Int] {
  var value: Int = 0
}

エラーはそれを言います

タイプCell[Cell.this.NEXT]のトレイトCellTの変数nextをオーバーライドします。nextの変数のタイプは互換性がありません

ここでは、と同じthisタイプになることは明らかですが、それでもエラーが発生します。タイプのすべてを返すことができるはずであるが、このタイプはクラスタイプパラメータと同じように必要ではないはずであるとScalaにどのように伝えることができますか?それ以外の場合は使用できますが、制限が厳しすぎます。たとえば、メソッドがタイプインスタンスのみを返すように制限されます。しかし、他のタイプのインスタンスに再割り当てできるようにしたいと思います。VAL <: AnyValNEXT <: AnyValnextCell[A <: AnyVal][VAL <: AnyVal][VAL]Cell[Int]nextCell[Int]nextCell[*]

4

3 に答える 3

2

next他のCell[*]タイプのインスタンスに再割り当てできるようにする場合は、既存のタイプを使用できます

trait CellT[VAL <: AnyVal] {
  var value: VAL
  var next: CellT[_ <: AnyVal]
}

abstract class Cell[VAL <: AnyVal] extends CellT[VAL] {
  var next: CellT[_ <: AnyVal] = this // defaults to `this`
  override def toString = "Cell(%s,%s)".format(value, if(next == this) "this" else next.toString)
}

// impl example:
class CellInt extends Cell[Int] {
  var value: Int = 0
}

class CellBoolean extends Cell[Boolean] {
    var value = false
}

var c1 = new CellInt
var c2 = new CellBoolean

println(c1)
c1.value = 1
println(c1)
c1.next = c2
println(c1)

println(c2)
c2.value = true
println(c1)
println(c2)

出力:

Cell(0、this)
Cell(1、this)
Cell(1、Cell(false、this))
Cell(false、this)
Cell(1、Cell(true、this))
Cell(true、this)

于 2012-09-13T17:19:18.383 に答える
1

ここで、これがタイプVAL <:AnyValであり、これはNEXT <:AnyValと同じであることは明らかです。

いいえ、同じではありません。同じ制約を共有しているだけです。NEXTはまだ指定されていません。その後、次のようにCellをサブクラス化するとします。

class StringNextCell extends Cell {
    type NEXT = String
}

さて、StringNextCell.nextタイプであるはずですCell[String]が、Cellからの宣言はそれを次のように宣言しますCell[Int]

于 2012-09-13T17:39:42.213 に答える
1

これは、警告ほど正確な答えではありません。私は1か月前に非常によく似たコードを作成しましたが、Scalaのタイピングに関しては、粗い方が良いことを学ぶのに何度も繰り返しました。

Scalaタイプのパラメーターチェックはコンパイル時のみであるため、多くの場合、思ったよりも粗いことに注意してください。X [Foo <:Bar]がX [_]として扱われていることに気付くだけで、コードをコンパイルするのに15分を費やすのは本当に面倒です。

次の項目から始めることをお勧めします。

abstract class Cell[VAL] {
    var value: VAL
    var next: Cell[_]
}

差し迫ったニーズがある場合にのみ、より具体的になります。次のタイプを知る必要がある場合は、とにかく明示的なランタイムチェックを行う必要がある可能性があります。

于 2012-09-13T17:45:53.177 に答える