Search code examples
iosprotocolsswift4

Swift Protocol Where Constraint with == vs :


I have Following Code (please ignore spell mistakes :))

protocol Vehical {
    var wheelsCount:Int {get}
}

protocol LightVehical:Vehical {
    func tankWithPetrol (liters:Int)
}

protocol HeavyVehical:Vehical {
    func tankWithDisel(liters:Int)
}

protocol OwnsVehical {
    associatedtype VechicalType = Vehical
    var vehical:VechicalType {get}
}

// Here I have == for constraint  
extension OwnsVehical where VechicalType == HeavyVehical {
    func fillTankWithDisel() {

    }
}
 // Light Vehicle
struct VolVOV90 : LightVehical {

    var wheelsCount: Int = 4

    func tankWithPetrol(liters: Int) {

    }
}
     // Heavy Vehicle

struct Van : HeavyVehical {
    func tankWithDisel(liters: Int) {

    }

    var wheelsCount: Int = 6


}

struct PersonWithHeavyVehical:OwnsVehical {
    typealias VechicalType = Van
    let vehical = Van()
}

Now when I tried

let personWithHeavyV = PersonWithHeavyVehical()
personWithHeavyV.fillTankWithDisel() // It is not compiling with ==

If I change

extension OwnsVehical where VechicalType == HeavyVehical 

With

extension OwnsVehical where VechicalType : HeavyVehical 

Code Compiles successfully I didn't find the diff between == And : Anyone can help me to understand it Thanks in advance


Solution

  • When you do:

    extension OwnsVehical where VechicalType == HeavyVehical

    you're telling the compiler that the VechicalType must be a HeavyVehical type. This means that the method fillTankWithDisel will only be available to OwnsVehical whose VechicalType is a HeavyVehical. That's why you can't call fillTankWithDisel on personWithHeavyV because personWithHeavyV is not a HeavyVehical, it's a Van.

    When you do:

    extension OwnsVehical where VechicalType : HeavyVehical

    you're telling the compiler that the VechicalType conforms with the HeavyVehical protocol, thus you're allowed to call personWithHeavyV.fillTankWithDisel because personWithHeavyV, by conforming to OwnsVehical, with no further restriction, can call fillTankWithDisel.

    If you want personWithHeavyV.fillTankWithDisel() to compile you'd have to change your implementation of the struct PersonWithHeavyVehical to the following:

    struct PersonWithHeavyVehical: OwnsVehical { typealias VechicalType = HeavyVehical let vehical = Van() }

    now you have a personWithHeavyV whose VechicalType is a HeavyVehical thus allowing you to call the desired method.