【问题标题】:Why Swift requires override of designated initializer of generic superclass?为什么 Swift 需要重写泛型超类的指定初始化程序?
【发布时间】:2016-08-25 18:24:44
【问题描述】:

根据 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

【问题讨论】:

  • 我做了更多测试,问题似乎是默认值。从您的示例中取出=5,其中 none 会导致编译器错误。

标签: swift generics compiler-errors initializer


【解决方案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> {
}

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

【讨论】:

  • 我怀疑,尽管我当然无法证明,在幕后证明编译器感到困惑的是,在没有 value 的情况下调用 init(value: Int = 5) 与调用 @987654325 相同@。我不知道为什么在泛型的情况下这会令人困惑,但这就是您的示例似乎指向的方向。
【解决方案2】:

我实际上填写了一个从泛型类继承的错误报告:

又回到了去年11月,还没有得到答案,所以¯_(ツ)_/¯

【讨论】:

  • 谢谢。知道我并不是唯一一个遇到这个问题的人,这绝对是有帮助的。同时,我不能将此消息视为答案,因为它既不是文档也不是关于该主题的快速演变讨论。
  • 我同意:非常有趣,但这是评论,不是答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-26
相关资源
最近更新 更多