AttilaTheFun
AttilaTheFun

Reputation: 701

Swift dynamicType does not work with generic function

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

Answers (1)

ABakerSmith
ABakerSmith

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

Related Questions