Associated types in protocols

You can also add an associated type as a protocol member. When using associatedtype in a protocol, you’re simply stating there is a type used in this protocol — without specifying what type this should be. It’s up to the protocol adopter to decide what the exact type should be.

This lets you give arbitrary names for types without specifying exactly which type it will eventually be:

protocol WeightCalculatable { associatedtype WeightType

func calculateWeight() -> WeightType

}

This delegates the decision of the return type of calculateWeight() to the protocol implementation.

You can see how this works in the two examples below:

class HeavyThing: WeightCalculatable {

// This heavy thing only needs integer accuracy typealias WeightType = Int

func calculateWeight() -> Int { return 100

}

}

class LightThing: WeightCalculatable {

// This light thing needs decimal places typealias WeightType = Double

func calculateWeight() -> Double { return 0.0025

}

}

In these examples, you use typealias to be explicit about the associated type. This usually isn’t required, as the compiler can often infer the type. In the previous examples, the return type of calculateWeight() makes it clear what the associated type should be, so you can remove typealias.

You may have noticed that the contract of WeightCalculatable now changes depending on the choice of associated type in the adopting type. Note that this prevents you from using the protocol as a simple variable type, because the compiler doesn’t know what WeightType will be ahead of time:

// Build error!

// protocol 'WeightCalculatable' can only be used as a generic

// constraint because it has Self or associated type requirements. let weightedThing: WeightCalculatable = LightThing()

You’ll learn all about generic constraints in the next chapter.

results matching ""

    No results matching ""