Generics in Swift Explained (How To)

Written by: Reinder de Vries, March 12 2017, in App Development

Generics Swift iOS

Generics are one of the most powerful features of Swift. In this article you’ll look at how they work, and what you can do with them.

This article is a preview of the new Foundation series here on In Foundation you’ll learn programming with Swift. It’s a available in the LearnAppMaking courses on iOS app development with Swift. Instead of using Swift to build apps, Foundation isolates programming concepts so you can better grasp their syntax and how to use them.

Let’s go!

How to use generics in Swift: To Tweet

What Are Generics?

Generics let you write clear, flexible and reusable functions. It allows you to avoid duplication of functions, and lets you write your code in a clear and expressive manner.

Swift is a strong-typed language, and that means that when you define a type for a variable – you always must do that – you can’t change it later. Neither can this variable contain different types, because it can only have one type. With generics you can specify a “generic type” – a type that’s loosely defined, and for instance constrained by its relation to other variable types.

Complicated? Read on…

Learn how to build iOS apps

Get started with iOS 11 and Swift 4

Sign up for my iOS development course Zero to App Store and learn how to build professional iOS 11 apps with Swift 4 and Xcode 9.

Why Use Generics?

Let’s look at an example to see why you would use generics to solve a programming problem.

This is a function for Mary’s farm:

func marysFarm(goose: Int, pigs: Int)
    print("Mary's farm has \(goose) geese and \(pigs) pigs")

marysFarm(goose: 5, pigs: 2)
// Outputs: "Mary's farm has 5 geese and 2 pigs"

Straightforward, right?

Now, let’s say Mary wants to also define the amount of geese and pigs she has as decimal-point numbers, or Doubles as we know them.

In order to do that, we need to define a second function with a new name marysFarmAsDoubles and different function parameters!

func marysFarmAsDoubles(goose: Double, pigs: Double)
    print("Mary's farm has \(goose) geese and \(pigs) pigs")

marysFarmAsDoubles(goose: 3.4, pigs: 9.1)
// Outputs: "Mary's farm has 3.4 geese and 9.1 pigs"

In the example above we define a second function that takes Double parameters, instead of Ints.

Now, Mary also wants to have the option to spell out the numbers as words. Again, we have to define a new third function that takes Strings as function parameters…

func marysFarmAsStrings(goose: String, pigs: String)
    print("Mary's farm has \(goose) geese and \(pigs) pigs")

marysFarmAsStrings(goose: "three", pigs: "six")
// Outputs: "Mary's farm has three geese and six pigs"

This isn’t ideal. We now have three functions that all have exactly the same functionality, the same code, but their function signatures are all different. Only because Mary wanted to define her farm in Int, Double and String

What if we could code those functions differently? That’s where generics come in.

Learn how to code your own iOS apps by mastering Swift 4 and Xcode 9 » Find out how

Generic Functions And Type Parameters

Check out this generic function:

func marysFarm<T>(goose: T, pigs: T)
    print("Mary's farm has \(goose) geese and \(pigs) pigs")

See how the function definition has changed? It’s got two new characteristics:

  • <T> right after the function name
  • T as parameter types

T is a placeholder type parameter. Instead of saying: the parameter must be of type Int or String, you simply indicate: the type can be anything, as long as both goose and pigs have the same type (they’re both T).

You have to declare a placeholder before you can use it in the parameters of the functions. That’s what happens right after the function name. You put an arbitrary name, like T or P, between angle brackets < >.

Now, let’s check out what happens:

func marysFarm<T>(goose: T, pigs: T)
    print("Mary's farm has \(goose) geese and \(pigs) pigs")

marysFarm(goose: 5, pigs: 3)
marysFarm(goose: 3.9, pigs: 2.1)
marysFarm(goose: "three", pigs: "seven")

You define the function marysFarm(goose:pigs:) once, and call it three times, each with different parameter types.

Nice! You’ve now saved yourself a whole lot of code, made the code more expressive, and easier to maintain.

Generics Are Everywhere…

Now, the cool thing is: if you’re coding Swift, you’ve been using generics all along without knowing it.

Let’s take the + operator, for instance. To Swift, that operator is just another function. It takes two parameters: the left-hand side of the operator, and the right-hand side.

Like this:

let result = 3 + 5

If that + operator looked a bit different, more like a function, it could just be:

let result = add(3, 5)

Guess what happens if you try to add two Doubles

let result = 2.1 + 3.9

Or even two strings:

let result = "hello" + "world"

The + function is a generic itself, that’s why it can perform addition for all kinds of variable types! As long as the left-hand side and the right-hand side have the same type, the + operator can add them.

OK, here’s another:

let a = [Int]()
let b = [String]()
let c = [Vehicle]()

Arrays are generics too! That’s why you can put virtually any kind of object in an array. The same goes for dictionaries and the - operator, for instance.

Protocols vs. Generics

So why not just use protocols, instead of generics?

Protocols serve a different purpose, although it’s similar. You use protocols to define rules that implementors have to follow. Generics don’t define any rules, they just say: you can put “anything” in this parameter.

Protocols say something about the structure of your code, whereas generics say something about its types, and relations between types.

Protocols do have a function together with generics. Take a look at this function:

func equal<T>(a:T, b: T) -> String
    return a == b ? "YES" : "NO"

let result = equal(a: 3, b: 3)

It’s an alias for the == equality operator, which outputs YES when a is equal to b and NO when they’re not equal, using the ternary conditional operator.

You cannot use generics this way. In order to use the == equality operator, on line 3, a and b must be equatable. Swift needs to be able to find out whether a and b are the same, so whatever T is, it needs to be “equatable.” You could say that anything that’s equatable “has the ability to be equal or inequal.”

Swift has defined a protocol for this characteristic called Equatable. Any class that conforms to Equatable is by definition equatable. Examples are String and Int, of which you can easily figure out if they’re exactly the same. For more complex objects, such as arrays and classes, it’s harder – how do determine if two instances of Car are exactly the same?

When you execute the above code, Swift will tell you:

error: binary operator '==' cannot be applied to two 'T' operands

Below that, in the sandbox, Swift will show a whole list of objects it can equate. Unfortunately, it won’t tell us the protocol T must conform to: Equatable.

Changing the function is easy now, T simply needs to conform to a protocol. You’ve seen that before!

func equal<T: Equatable>(a:T, b: T) -> String

Try it out yourself!

func equal<T: Equatable>(a:T, b: T) -> String
    return a == b ? "YES" : "NO"

let result = equal(a: "hello", b: "hello")

Try out Swift in the IBM Swift Sandbox

Here’s a few examples of other protocols:

  • Comparable, in order to use the <=, > and >= operators
  • Hashable, in order to compare objects, arrays and dictionaries
  • Printable, in order to print the value of an arbitrary variable


When do you use generics as a practical app developer?

Fortunately you seldom define your own generics, or create functions with generics. Unless you’re writing a library or foundational code, you won’t often have to define a function that takes generic input.

You do use generics all the time. As you could see in the examples above, generics are everywhere. It helps to know how generics work!

Read more about generics:

Enjoyed this article? Feel free to share it!

How to use generics in Swift: To Tweet

Reinder de Vries

Reinder de Vries is a professional iOS developer. He teaches app developers how to build their own apps at Since 2009 he has developed a few dozen apps for iOS, worked for global brands and lead development at several startups. When he’s not coding, he enjoys strong espresso and traveling.

Leave a Reply

Required to post: Your real name and email address, and a pleasant demeanor. Your email address will not be published. Markdown is supported.