我有一个名为LLLinkedList
的课程,它定义了subscript
:
class LLLinkedList<L> {
//other properties, functions and initializers...
subscript(range: Range<Int>) -> LLLinkedList {
get {
//return something
}
set {
//set something
}
}
}
现在subscript
显然需要Range<Int>
并返回LLLinkedList
。
我还定义了LLLinkedList
的子类LLArray
:
class LLArray<A>: LLLinkedList<A> {
//other properties, functions and initializers...
}
LLArray
还实现subscript
获取Range<Int>
并返回LLArray
:
subscript(range: Range<Int>) -> LLArray {
get {
//return something
}
set {
//set something
}
}
由于LLArray
是LLLinkedList
的一种类型,因此无法覆盖子类中的subscript
(因为参数和返回类型因此是相同)。
如果我不覆盖下标,编译器会对我大喊:
<stdin>:1173:5: error: cannot override mutable subscript of type '(Range<Int>) -> LLArray<A>' with covariant type '(Range<Int>) -> LLLinkedList<A>'
subscript (range: Range<Int>) -> LLArray {
^
现在这个错误对我有意义,但我该如何环绕它呢?
或者我甚至必须实施新的subscript
?
我实现了一个新的subscript
,因此在使用返回的实例时,会返回LLArray
而不是LLLinkedList
,从而防止需要向下转换。
答案 0 :(得分:2)
基本上,没有办法用你想做的读/写下标,因为下标的返回类型实际上出现在LLLinkedList
类的协变和逆变位置({{1下标的一部分将其置于协变位置; get
部分处于逆变位置)。因此它不能在子类中改变,因为它会打破替换原则。没有多少摆弄协议和扩展可以解决它(如果确实如此,它是一个编译器错误)。
这里的一种可能性是将下标分成两个方法:getter方法可以有一个协变返回类型,而setter仍然总是接受更通用的set
类型。