为什么Swift需要覆盖泛型超类的指定初始化器?

时间:2016-04-30 17:16:10

标签: swift generics compiler-errors initializer

根据Apple的文档,Swift不需要覆盖初始化程序。在以下代码示例中,Bar继承了Foo的初始化程序:

class Foo {
  let value: Int
  init(value: Int = 5) {
    self.value = value
  }
}

class Bar: Foo {
}

我们在Foo添加一些通用内容,例如class Foo<T> { Xcode会向我们提供错误Initializer does not override a designated initializer from its superclass。是否有文件或快速进化讨论解释了为什么会发生这种情况?

更新。似乎通用不是覆盖要求的主要原因。以下是如何使用泛型定义不需要覆盖指定初始化程序的类的选项:

protocol FooProtocol {
    associatedtype T
}

class Foo<U>: FooProtocol {
    typealias T = U

    let value: Int
    init(value: Int, otherValue: T) {
        self.value = value
        self.otherValue = otherValue
    }
}

class Bar: Foo<Int> {
}

然而,还有另一个有趣的行为观察。定义初始化器,如下面的原因覆盖要求:

init(value: Int = 5) {
    self.value = value
}

有趣的是,在指定的初始化程序中添加一个以下参数会导致此覆盖要求消失:

init(value: Int = 5, otherValue: T) {
    self.value = value
}

更新2 。我无法找到这种行为的合理解释,此时我将其报告为编译器错误 - https://bugs.swift.org/browse/SR-1375

2 个答案:

答案 0 :(得分:1)

我实际填写了一个bug报告,用于继承泛型类:

enter image description here

它回到去年11月的 并且还没有得到答案,所以¯_(ツ)_ /¯

答案 1 :(得分:1)

这显然是一个错误。此外,尽管通过子类化泛型来引发 ,但其邻近的原因是默认值。编译得很好:

class Foo<T> {
    let value: Int
    init(value: Int) {
        self.value = value
    }
}

class Bar: Foo<String> {
}

但这不是:

class Foo<T> {
    let value: Int
    init(value: Int = 5) {
        self.value = value
    }
}

class Bar: Foo<String> {
}

这种没有区别的任意区别肯定表明这是一个编译器错误。