Reputation: 701
Say I have a protocol:
protocol VehicleModel {...}
It is implemented by a number of different structs. (e.g. CarModel, TruckModel, etc.) I have a generic method to get the vehicle's 'model identifier'.
func modelIdentifierForVehicle<V: VehicleModel>(vehicleType: V.Type) -> String {
return "\(vehicleType)"
}
If I call modelIdentifierForVehicle(CarModel.self) this returns "Car" just fine. But if I have a polymorphic collections of VehicleModel's and I try to call modelIdentifierForVehicle(model.dynamicType) on each of them, Xcode says "Cannot invoke 'modelIdentifierForVehicle' with argument list of type (VehicleModel.Type)" Why is this? And how can I work around it?
Upvotes: 0
Views: 128
Reputation: 22939
Since you're only converting vehicleType
to a String
in modelIdentifierForVehicle
, I would argue why you need to use constrain V
to VehicleModel
, or even use generics at all:
func typeIdentifier(t: Any.Type) -> String {
return "\(t)"
}
let vehicles: [VehicleModel.Type] = [CarModel.self, TruckModel.self]
typeIdentifier(vehicles[0]) // CarModel
If there's a reason you need use a VehicleModel
, assuming VehicleModel
doesn't use Self
or associated type requirements, you could do:
func modelIdentifierForVehicle(vehicleType: VehicleModel.Type) -> String {
return "\(vehicleType)"
}
If you're using Swift 2, you could instead use a protocol extension:
extension VehicleModel {
static var modelIdentifier: String {
return "\(self.dynamicType)"
}
}
// The array from earlier.
vehicles[1].modelIdentifier // TruckModel.Type
Upvotes: 1