只是为了获得更多使用Scala的经验,并且作为一项实验,我正在实现一个类似List
的类,但是实现为IndexedSeq
的列表,其索引为第一个元素; tail
只返回索引递增的副本,前置Array
s为O(1),而附加Array
s为O(m),m =列表长度< =元素数量。
我遇到了函数返回类型的问题。几乎每个方法都有类型参数[R >: T : ClassManifest, A <: R : ClassManifest]
,T
是BlockList
的类型参数。有时这些方法只返回其他方法,但在这些情况下,我从Eclipse中收到错误,说它正在查找类型BlockList[R]
但找到类型BlockList[Any]
。 R
和T
不应该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
}
答案 0 :(得分:3)
R不应该是T和A的最低常见超类型吗?
不,因为R
是上限。 R
可以是 T
的任何超类,唯一满足该范围的类是Any
。
想象一下,例如,R
是AnyRef
- 您可以在其上调用eq
等方法,如果Int
通过则会中断。
所以,虽然R
可以低于Any
(可能大部分时间都是这样),但在你声明它时,人们不能认为它是低于Any
。
但是,我认为上述内容与您的问题没有任何关系。您报告的错误会显示在这些行中,对吗?
Array[R](x) |: this
this :| Array[R](x)
另一个也有:|
。您没有显示从Array
到Build
的任何隐式转换,并且:|
方法都没有Array
作为参数(数组不是IndexedSeq
)
所以,当你写
this :| Array[R](x)
这会调用def |: [R1 >: T : ClassManifest, A <: R1] (x: A): BlockList[R1]
(我已将R
更改为R1
nto以与参数中的R
混淆),其中A
的类型} Array[R]
,T
和Array[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`,我无法预测其他内容。