Protocols are one of the most important aspects of the Swift programming language. They consist of properties, methods, and other requirements that define the interface of any particular conforming type. Associated types are a great way to enhance the capabilities of protocols making them more generic and flexible.
Let us take a simple example of a protocol implementation:
Having your own business is what everyone dreams of. Every business has its own product specializations. So we maintain a product store for each business type that we have.
In the above code, we created a
Business protocol that has a
storeproperty inside it that holds products for that business in a hash map. Every product should conform to the
ProductType protocol which has a
id associated with it. We have defined two products one is
PharmacyProduct and the other is a
GroceryProduct belonging to two different businesses i.e
We now own two businesses, each with its own fully filled store. We are about to start our new venture but wait !! Do you see what the issue is over here?
Your Business store holds products that conform to
ProductType. A Grocery business could never know what type of product it is. It can be a
GroceryProduct or a
PaharmacyProduct. Everything works fine till they conform to the
ProductType protocol. Now how we can avoid this? This brings us to our first use case of associated type i.e to have more control over the type.
1. Conforming types to have more control over the type of protocol properties and methods
As you saw in the above example any businesses could not know the exact type of product that is being added to their store. Though you can put a check on the identifier or any other tricks, it would be super awesome if we could someway control the type of product that enters our store.
Let us introduce the
associatedtype to our protocols.
A couple of interesting things happening in the above code. First, we introduced
associatedtype keyword into our protocol. We then constrained it to
store now holds the associated type as a product.
On the conformation part, we are forced by the compiler to provide the associated type with constraints as a concrete type instead of a protocol, the reason being that a concrete type can only conform to a protocol. Try writing
typealias Product = ProductType and you would see the compiler hit you with an error.
Did you notice in the conformation part the associated type being represented as a
typealias. The reason behind that is the compiler understands this as some sort of placeholder which will be filled with the type at compile time.
Let us slightly refactor the above code, as Swift is smart for type inference.
Isn’t that cool !!
Moving on to the next reason why would you want to use an associated type, we have recursive constraints.
2. Type constraints for individual properties and methods in protocols and Recursive Constraints
We all are ambitious and want to scale our business and our brand to the next level. In order to do that we need to have multiple branches of our business. We need to take care of an important part here. Our business though can function on its own but their product type should be the same as that of our main branch. In the end, they are a subsidiary of ours. So let us modify our business interface to handle that.
We introduced a new associated type
Retailers that is constrained to be of a
Business type. This is called a recursive constraint where you constrained the property within a protocol to that type itself. And with the introduction of the
where keyword, we constrained it to have the same product as the store has.
Now Swift Compiler will ensure that the product type of your main branches and all your retailers will be the same.
These are some of the few useful areas where you can use a protocol
associatedtype. Although you are never limited to this. Keep experimenting and keep learning.
I would love to hear from you
You can reach me for any query, or feedback, or just want to have a discussion through the following channels: