Lee Whitney III
Lee Whitney III

Reputation: 10978

Swift Generics: No accessible initializers

Why does the code below compile with an error: 'T' cannot be constructed because it has no accessible initializers

let drive = Drive<Car>()

class Car : Steering {
    init() { }
    func turnWheel() { }
}

protocol Steering {
    func turnWheel()
}

class Drive<T:Steering> {    
    func Go() {
        var vehicle = T()
        vehicle.turnWheel()
    }
}

Upvotes: 3

Views: 10804

Answers (2)

Joachim Isaksson
Joachim Isaksson

Reputation: 181077

You - as the compiler says - need to require a parameterless initializer in your declaration of Steering.

Since T is only required to implement the Steering protocol and you want to construct it using T(), the protocol Steering needs the parameterless initializer to be guaranteed to be constructable like that.

protocol Steering {
    init();
    func turnWheel()
}

class Car : Steering {
    required init() { }
    func turnWheel() { }
}

Upvotes: 4

vcsjones
vcsjones

Reputation: 141678

Because T is constrained to Steering. Your constraint says, "T can be any type that conforms to the Steering protocol. However, if I have this class:

class Airplane : Steering {
    init(altitude : Int) {
    }

    func turnWheel() {
    }
}

All of the sudden I have a type that conforms to Steering and T, but does not have an init that accepts zero parameters.

The solution is to add the init to your protocol, ensuring anything that conforms to it has the correct init.

protocol Steering {
    func turnWheel()
    init()
}

Upvotes: 6

Related Questions