Swiftgenerics超类init在构造子类时不可访问
我有以下代码:
class ILProperty<T> { var value: T? init(_ value: T) { self.value = value } } typealias ILStringProperty = ilStringProperty<String> class ilStringProperty<String>: ILProperty<String> { } let x = ILStringProperty("X")
最后一行是一个编译错误:
“ILStringProperty”不能被构造,因为它没有可访问的初始化器
如果我重写init:
override init(_ value: String) { super.init(value) }
将工作,但我不喜欢它。 当我不添加/修改它时,为什么我需要覆盖它?
难道我做错了什么?
更新 :后续问题来自Nikita Leonov和Icaro的答案
首先关于所有的属性必须有默认值,我认为我满足了这个规则,其中一个可选的var默认值为零,不是吗? 即使我写var value: T? = nil
var value: T? = nil
解决不了。
然后从相同的文档部分“自动初始化程序inheritance”:
如果满足某些条件,超类初始化器会自动inheritance
一个条件是:
如果你的子类没有定义任何指定的初始值设定项,它将自动inheritance它的所有超类指定的初始值设定项。
我在哪里认为上面的代码确实符合。 这实际上将工作,如果我不会使用generics:
class ILProperty { var value: Any? init(_ value: Any) { self.value = value } } class ILStringProperty: ILProperty { } let x = ILStringProperty("X")
这个规则是否也适用于generics类?
代码示例中的最后一行不再给出编译错误(自Swift 3以来)。 在Swift 3语言变更中没有提到这一点,所以我只能假设这是一个错误。
从苹果文档 :
Swift为任何为其所有属性提供默认值的结构体或基类提供了一个默认的初始值设定项,并且本身不提供至less一个初始化项。 默认的初始化器只是创build一个新的实例,并将其所有属性都设置为默认值。
你的类ilStringProperty不是基类,因为它从ILPropertyinheritance,所以它必须有一个初始化,如果你创build一个或重写一个无关紧要,因为你的类中至less有一个初始化,因为swift不会免费提供一个。
正如ganzogo提到,它似乎与最新的Swift(3.0)正常工作。 另外,为什么你要声明一个单独的类来分配给typealias
? 我已经在游乐场试过了,看起来没问题:
class ILProperty<T> { var value: T? init(_ value: T) { self.value = value } } typealias ILStringProperty = ILProperty<String> let x = ILStringProperty("X")
这里是苹果文档的另一个引用
与Objective-C中的子类不同,Swift子类默认不会inheritance它们的父类初始化程序。 Swift的方法避免了一个情况,即一个超类的简单初始值设定项被一个更专门化的子类inheritance,并被用来创build一个未完全或正确初始化的新子类。
在苹果的Swift编程语言文档部分“初始化inheritance和覆盖”。
我不明白你的沮丧,但Swift处理初始化的方式在概念上更好。