Search code examples
swiftswift3xcode8access-levels

Access levels of custom initializers in Swift 3.1


Quote from The Swift Programming Language (Swift 3.1):

Custom initializers can be assigned an access level less than or equal to the type that they initialize. The only exception is for required initializers (as defined in Required Initializers). A required initializer must have the same access level as the class it belongs to.

If so, why does this code compile and work?

private class GoofyClass {
    public init(mood: String) {}
    public required init(isCrazy: Bool) {}
}

private let shock = GoofyClass(mood: "shocked")
private let crazy = GoofyClass(isCrazy: true)

Solution

  • In Swift, members of a class or struct with a less restrictive access level than the class/struct itself are automatically downgraded to the same level as the class/struct. I believe this is a deliberate design decision on the part of the language designers.

    In your case, assuming the class is declared at the top level in the file (i.e. it is not nested inside another type), the inits you have declared public are, in fact, fileprivate.

    The only exception is for required initializers (as defined in Required Initializers). A required initializer must have the same access level as the class it belongs to.

    This is referring to the fact that you cannot make the access level of a required initialiser more restrictive than its class e.g.

    open class Foo 
    {
        internal required init() // error
    }