Understanding Swift Generics

As with every high level concept in programming, it took some time for me to grasp generics. Many developers consider it an advanced topic in iOS programming. Its practical use in application logic however, urged me to write an article on the subject.


There are lots one can do with generics. The aim of this article is to provide a foundation so that you may start using generics in your code when the situation requires it. We will illustrate its use through the scenario of a customer shopping for items at a supermarket. Let’s begin by creating a customer object.


swift generics

The customer object we created has a name, a shopping cart, which is an Any array, a wallet, and a method called pay. These properties and method pretty much defines all we need to be a functioning customer at a supermarket. Next we will create a supermarket object where the customer can do some shopping.


swift generics

Aside from the supermarket having a name, the checkout method defined inside this object is where we will implement the logic to checkout a customer. The final step in our setup is to create some items the customer can buy.


swift generics

Ok, let’s now begin implementing a solution to calculate our total when the customer is checking out. Since each grocery item represents a different object, we can conform them to a protocol so that we may uniformly apply a method to them.


swift generics

We now have created a protocol called SuperMarketItem. This protocol defines a single method calls cost, which returns a Float that stands for the price of the item. We then conform our grocery items to this protocol.


Let’s now change the shopping cart from an Any Object array to one that uses the protocol as a data type. Read part two of my protocol article if you are confused.


swift generics

Ok, so we’re making progress. The final step now is to calculate the total of our customer’s shopping cart using simple logic. An concise solution is provided below.


swift generics

The solution used in this example is a reduce function that return the total price of the shopping cart array passed into the method. After creating a shopping cart array and initializing a customer and supermarket, our reduce technique is working just fine.


The question is however, why didn’t we use generics for our shopping cart array instead? Although protocol data types and generics are both abstractions, they have major differences. Let’s see what they are.


Generics serve as placeholder abstractions. It is a way of saying, this array can be composed of any specific object that matches this generic profile. The generic is not a data type. Rather, it is a placeholder for any object that meets the profile of the generic. Let’s see what this means in code. We’ll start by changing the shopping cart from one that uses the protocol as a data type and replace it with a generic object T that conforms to the SuperMarketItem protocol.


swift generics

We have converted our shopping cart to an array that uses a generic placeholder. Our array can hold any data type that meets the generic profile defined above. In this case, any object that conforms to the SuperMarketItem protocol. The exact data type of the array is not specified yet however, it is when we create the object that we specify what the actual data type is for that particular instance.


swift generics

Since the apple object meets the generic profile due to the fact that it conforms to the SuperMarketItem protocol, it can be used as the actual data type when the object is formed. Unlike the protocol example however, I cannot store other objects outside of apple into the array. Look at what happens when the attempt is made.


swift generics

Again, since I specified that Apple will be the data type in this particular instance through the syntax , only apple objects can go inside the array. Despite the fact that both cherries and apple conform to the same protocol, they remain different data types nonetheless. Generics serve as a placeholder for any specific type that meets its profile. It is not a data type in of itself.


I could however declare another customer instance and place cherries as the data type when defining the generic parameter. Since cherries match the generic profile, it will be accepted for the instance. But remember, only cherries can go into that array!


swift generics

That… in a nutshell, is the true essence of generics. They serve as placeholders when you are not sure what specific data type will be stored but have a clear idea of what the general profile of the object should look like. Wonderful instruments aren’t they? Now that we have the total, let’s not forget to pay ;)


swift generics

I hope you enjoyed my article on generics. Rather than providing you a traditional example where they are successfully utilized, I think demonstrating their limitation can be just as enlightening in understanding how to use them. If you did not grasp everything in this article please be patient, software engineering is a marathon, not a race. Just keep at it and the dust will clear


good_news

Keep Coding!