覆盖在子类中返回协变类型的下标

时间:2015-02-02 14:31:30

标签: class swift override covariance subscript

我有一个名为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
    }
}

由于LLArrayLLLinkedList的一种类型,因此无法覆盖子类中的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,从而防止需要向下转换。

1 个答案:

答案 0 :(得分:2)

基本上,没有办法用你想做的读/写下标,因为下标的返回类型实际上出现在LLLinkedList类的协变和逆变位置({{1下标的一部分将其置于协变位置; get部分处于逆变位置)。因此它不能在子类中改变,因为它会打破替换原则。没有多少摆弄协议和扩展可以解决它(如果确实如此,它是一个编译器错误)。

这里的一种可能性是将下标分成两个方法:getter方法可以有一个协变返回类型,而setter仍然总是接受更通用的set类型。