为什么必须使用元类型值构造类类型为'someClass'的对象使用'required'初始值设定项?

fuj*_*471 14 swift

class Animal {
    class func generate() -> Animal {
        return self()
    }
}
Run Code Online (Sandbox Code Playgroud)

编译器抱怨构造类型为"Animal"的对象,其元类型值必须使用"required"初始值设定项

我能理解这一点.如果我写这样的子类:

class SubAnimal: Animal {
    let head: Int
    init(head: Int) {
        self.head = head
        super.init()
    }
}
Run Code Online (Sandbox Code Playgroud)

它将继承Animal的类方法,generate()但不会继承其默认的初始化程序init().所以SmallAnimal.generate()实际上是调用SmallAnimal(),但SmallAnimal没有初始化程序init()!当然这是编译器想要阻止的.

令我困惑的是一个类似的问题.

class someClass {

}
let anotherClass = someClass.self
let anotherObject = anotherClass()
Run Code Online (Sandbox Code Playgroud)

编译器仍抱怨构造类型为"Animal"的对象,其元类型值必须使用"required"初始化器.

这一次,我无法理解.anotherClass是一个元类型值,但会导致什么不好的结果?

我知道如何解决这个问题,添加required init() {}是解决方案.但我真的想知道第二种情况的原因.

Aar*_*ger 15

考虑我们还有一个子类的情况:

class SomeClass {

}

class SomeSubclass : SomeClass {

}
Run Code Online (Sandbox Code Playgroud)

如果将类类型存储在变量中:

var anotherClass = SomeClass.self
Run Code Online (Sandbox Code Playgroud)

变量anotherClass属于类型SomeClass.Type.

您可以稍后将此变量分配给子类:

anotherClass = SomeSubclass.self
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为SomeSubclass.TypeSomeClass.Type.此时,anotherClass()如果初始化程序未在子类中实现,则会失败.这是编译器正在防范的内容.

在您的示例代码中,这是不可能的:您使用let而不是var更改类型是不可能的.可能安全检查不够细致,不足以注意到这一点.