Scala:类型不匹配,返回BlockList [Any]而不是BlockList [R]

时间:2013-09-30 02:56:13

标签: scala generics generic-collections

只是为了获得更多使用Scala的经验,并且作为一项实验,我正在实现一个类似List的类,但是实现为IndexedSeq的列表,其索引为第一个元素; tail只返回索引递增的副本,前置Array s为O(1),而附加Array s为O(m),m =列表长度< =元素数量。

我遇到了函数返回类型的问题。几乎每个方法都有类型参数[R >: T : ClassManifest, A <: R : ClassManifest]TBlockList的类型参数。有时这些方法只返回其他方法,但在这些情况下,我从Eclipse中收到错误,说它正在查找类型BlockList[R]但找到类型BlockList[Any]RT不应该A是最低常见超类型吗?在这种情况下,第二个方法调用也应该返回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

}

1 个答案:

答案 0 :(得分:3)

  

R不应该是T和A的最低常见超类型吗?

不,因为R是上限。 R可以是 T的任何超类,唯一满足该范围的类是Any

想象一下,例如,RAnyRef - 您可以在其上调用eq等方法,如果Int通过则会中断。

所以,虽然R 可以低于Any(可能大部分时间都是这样),但在你声明它时,人们不能认为它是低于Any

但是,我认为上述内容与您的问题没有任何关系。您报告的错误会显示在这些行中,对吗?

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

另一个也有:|。您没有显示从ArrayBuild的任何隐式转换,并且:|方法都没有Array作为参数(数组不是IndexedSeq

所以,当你写

this :| Array[R](x)

这会调用def |: [R1 >: T : ClassManifest, A <: R1] (x: A): BlockList[R1](我已将R更改为R1 nto以与参数中的R混淆),其中A的类型} Array[R]TArray[R]的唯一超类型为Any,因此R1必须为Any,但Any R 1}}与this.:|[R, Array[R]](Array[R](x)), it would move things a little further. With the missing definitions that allow不同。

也许,如果你把它称为{{1}} Array`,我无法预测其他内容。