The introduction of Swift brings a new series of tools that make coding more friendly and expressive. Along with its simplified syntax, Swift borrows from the success of other languages to prevent common programming errors like null pointer exceptions and memory leaks.

To contrast, Objective-C has often been referred to as ‘the wild west’ of code. While extensive and powerful, many errors in Objective-C apps are discovered at runtime. This delay in error discovery is usually due to programming mistakes with memory management and type cast operations. For this essay, we’ll review a new design technique with Swift called generics and will explore how this allows data structures to be more expressive and type-safe.


As we’ve seen, data structures are the building blocks for organizing data. For example, linked lists, binary trees and queues provide a blueprint for data processing and analysis. Just like any well-designed program, data structures should also be designed for extensibility and reuse.

To illustrate, assume you’re building a simple service that lists a group of students. The data could be easily organized with a linked list and represented in the following manner:

  //student linked list structure
  class StudentNode {
      var key: Student?
      var next: StudentNode?    


While this structure is descriptive and organized, it’s not reusable. In other words, the structure is valid for listing students but is unable to manage any other type of data (e.g. teachers). The property Student is a class that may include specific properties such as name, schedule and grades. If you attempted to reuse the same StudentNode class to manage Teachers, this would cause a complier type mismatch.

The problem could be solved through inheritance, but it still wouldn’t meet our primary goal of class reuse. This is where generics helps. Generics allows us to build generic versions of data structures so they can be used in different ways.


If you’ve reviewed the other topics in this series, you’ve already seen generics in action. In addition to data structures and algorithms, core Swift functions like arrays and dictionaries also make use of generics. Let’s refactor the StudentNode to be reusable:

 //refactored linked list structure
  class LLNode<T> {
     var key: T?
     var next: LLNode<T>?

We see several important changes with this revised structure. The class name StudentNode has been changed to something more general (e.g., LLNode). The syntax <T> seen after the class name is called a placeholder. With generics, values seen inside angled brackets (e.g., T ) are declared variables. Once the placeholder T is established, it can be reused anywhere a class reference would be expected. In this example, we’ve replaced the class type Student with the generic placeholder T.


The power of generics can be now be seen through its implementation. With the class refactored, LLNode can now manage lists of Students, Teachers, or any other type we decide.

//new list of students 
var studentList = LLNode<Student>() 

//new list of teachers 
var teacherList = LLNode<Teacher>()


In addition to classes, generic functions can also be developed. As we saw in the previous sorting chapter, algorithms like insertionSort and bubbleSort rank sets of random numbers. Using generics, these algorithms can be refactored so they sort characters, as well as numbers:

func insertionSortG<T: Comparable>(sequence: [T]) -> [T] {
        //return the trivial cases
        guard sequence.count > 1 else {
            return sequence

        //mutated copy
        var output = Array(sequence)
        for primaryIndex in 0..<output.count {   
            let key = output[primaryIndex]
            for var secondaryIndex = primaryIndex; secondaryIndex > -1; secondaryIndex-- {
                print("comparing \(key) and \(sequence[secondaryIndex])")
                if key < output[secondaryIndex] {

                    //move into correct position
                    output.removeAtIndex(secondaryIndex + 1)
                    output.insert(key, atIndex: secondaryIndex)           
        return output        

Here’s example of a generic insertionSort algorithm. As part of the implementation, we must also consider the comparison of generic types. As a result, the type constraint Comparable is appended to the generic T placeholder. Native to Swift, Comparable is a simple protocol that ensures generic types conform to the Comparable specification.

Like this series? Subscribe to the newsletter and receive a free guide on iOS interview tips.