Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why must constructing an object of class type 'someClass' with a metatype value use a 'required' initializer?

Tags:

swift

class Animal {
    class func generate() -> Animal {
        return self()
    }
}

The compiler complains constructing an object of class type 'Animal' with a metatype value must use a 'required' initializer

I can understand this. If I write a subclass like this:

class SubAnimal: Animal {
    let head: Int
    init(head: Int) {
        self.head = head
        super.init()
    }
}

It will inherit Animal's class method generate() but won't inherit its default initializer init(). So SmallAnimal.generate() actually calls SmallAnimal(), but SmallAnimal doesn't have an initializer init()! Of course this is what the compiler want to prevent.

What confuses me is a similar problem.

class someClass {

}
let anotherClass = someClass.self
let anotherObject = anotherClass()

The compiler still complains constructing an object of class type 'Animal' with a metatype value must use a 'required' initializer.

This time, I cannot understand. anotherClass is a metatype value, but what bad result will be caused?

I know how to solve this problem, adding required init() {} is the solution. But I really want to know the reason for the second case.

like image 413
fujianjin6471 Avatar asked Aug 23 '15 04:08

fujianjin6471


1 Answers

Consider the case where we also have a subclass:

class SomeClass {

}

class SomeSubclass : SomeClass {

}

If you store the class type in a variable:

var anotherClass = SomeClass.self

The variable anotherClass is of type SomeClass.Type.

You can later assign this variable to a subclass:

anotherClass = SomeSubclass.self

This is valid because SomeSubclass.Type is a SomeClass.Type. At this point, anotherClass() would fail if the initializer is not implemented in the subclass. This is what the compiler is protecting against.

In your sample code, this is impossible: you used let instead of var so changing the type is impossible. It may be that the safety checks just aren't nuanced enough to notice this.

like image 194
Aaron Brager Avatar answered Oct 07 '22 01:10

Aaron Brager