0

Scala の経験を積むために、実験として、 のListような APIを持つクラスを実装しIndexedSeqていますが、最初の要素へのインデックスを持つ のリストとして実装されています。tailインデックスがインクリメントされたコピーを返すだけで、先頭に追加する s はArrayO(1) ですが、追加するArrays は O(m) です。m = リストの長さ <= 要素の数。

関数の戻り値の型に問題があります。ほぼすべてのメソッドには型パラメーターがあり[R >: T : ClassManifest, A <: R : ClassManifest]Tこれは の型パラメーターですBlockList。これらのメソッドが他のメソッドを返す場合もありますが、そのような状況では、Eclipse から type を探していたが typeBlockList[R]が見つかったというエラーが表示されBlockList[Any]ます。Rと の両方の最も一般的なスーパー タイプであってはTなりAませんか? その場合、2 番目のメソッド呼び出しも を返す必要がありBlockList[R]ますよね? 何が得られないのですか?型消去の問題を克服するためにいろいろ反省しClassManifestていますが、それでも問題があるかどうかはわかりません。

エラーは と の定義によるもの|:です:|

import collection.immutable.List
import reflect.ClassManifest
import annotation.tailrec

sealed abstract
class BlockList [+T] extends Seq[T] with Product {
...
}

object EmptyBlock extends BlockList[Nothing] {
...
}

class Build [T: ClassManifest](
private val block: IndexedSeq[T],
private val next: BlockList[T] = EmptyBlock,
private val index: Int = 0
) extends BlockList[T] {
require(!block.isEmpty && index >= 0 && index < block.length)

override def |: [R >: T : ClassManifest, A <: R] (x: A): BlockList[R] =
    Array[R](x) |: this //Return type error here

override def |: [R >: T : ClassManifest, A <: R : ClassManifest]
(blk: IndexedSeq[A]): BlockList[R] =
    if (blk isEmpty) this
    else new Build[R](blk, this)

override def :| [R >: T : ClassManifest, A <: R] (x: A): BlockList[R] =
    this :| Array[R](x) //Return type error here

override def :| [R >: T : ClassManifest, A <: R : ClassManifest]
(blk: IndexedSeq[A]): BlockList[R] = 
    if (blk isEmpty) this
    else new Build[R](block, next :| blk, index) //Type error here

}
4

1 に答える 1

3

R は、T と A の両方の最も一般的なスーパー タイプではないでしょうか?

いいえ、R上限があるためです。Rはの任意のスーパー クラスでありT、その範囲を満たす唯一のクラスは ですAny

たとえば、それRがあったと想像してみてください。次に、 on itAnyRefなどのメソッドを呼び出すことができます。これは、が渡さeqれると壊れます。Int

そのため、 whileはよりも低い値になるR 可能Any性があります (そして、おそらくほとんどの場合はそうなるでしょう) が、それを宣言する時点では、それが よりも低い値であると想定することはできませんAny

ただし、上記はあなたの問題とは何の関係もないと思います。あなたが報告したエラーはこれらの行に表示されますよね?

Array[R](x) |: this
this :| Array[R](x)

もう片方にも が:|入っています。Arrayからへの暗黙的な変換は表示されず、どのBuildメソッド:|Arrayパラメータとして取りません (配列は ではありませんIndexedSeq)。

だから、あなたが書くとき

this :| Array[R](x)

これは(パラメータの the と混同するために nto にdef |: [R1 >: T : ClassManifest, A <: R1] (x: A): BlockList[R1]変更Rしました) を呼び出します。ここで、のタイプはisであり、 and の唯一のスーパータイプはisであるため、 である必要がありますが、それは とは異なります。R1RAArray[R]TArray[R]AnyR1AnyAnyR

たぶん、this.:|[R, Array[R]](Array[R](x)), it would move things a little further. With the missing definitions that allow渡されるように Array` と呼んだ場合、私は他の多くを予測することはできません.

于 2013-09-30T03:55:22.337 に答える