【问题标题】:Overriding a subscript returning a covariant type in subclasses覆盖在子类中返回协变类型的下标
【发布时间】:2015-04-01 12:46:53
【问题描述】:

我有一个名为LLLinkedList 的类,它定义了一个subscript

class LLLinkedList<L> {
    //other properties, functions and initializers...

    subscript(range: Range<Int>) -> LLLinkedList {
        get {
            //return something 
        }
        set {
            //set something
        }
    }
}

现在subscript 显然接受Range&lt;Int&gt; 并返回LLLinkedList

我还定义了LLLinkedList 的一个子类,称为LLArray

class LLArray<A>: LLLinkedList<A> {
    //other properties, functions and initializers...
}

LLArray 还实现了一个subscript 接受一个Range&lt;Int&gt; 并返回一个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,从而避免向下转换的需要。

【问题讨论】:

  • 可以覆盖subscript,如果它是只读的(只有get,没有set)。另一方面,子类不能用更具体的 argument 类型覆盖 set

标签: class swift overriding covariance subscript


【解决方案1】:

基本上,没有办法用读/写下标做你想做的事情,因为下标的返回类型实际上出现在 LLLinkedList 类的协变和逆变位置(get 部分下标将其置于协变位置;set 部分置于逆变位置)。因此它不能在子类中改变,因为它会破坏替代原则。再多的修改协议和扩展都无法修复它(如果是这样,那就是编译器错误)。

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

【讨论】:

    猜你喜欢
    • 2017-03-20
    • 1970-01-01
    • 1970-01-01
    • 2020-11-05
    • 1970-01-01
    • 1970-01-01
    • 2019-06-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多