Advanced Swift Feature: Generics

A portrait painting style image of a pirate holding an iPhone.

by The Captain

on
April 15, 2023

Advanced Swift Feature: Generics

Generics allow you to write flexible and reusable code by defining functions, structures, and classes that can work with any type, as long as that type meets certain requirements. This feature is heavily used in iOS development and can greatly improve the efficiency of your code. Let's take a look at an example.

Generic Function

A generic function is a function that can work with any type. Let's create a function that swaps two variables:

func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
    let temp = a
    a = b
    b = temp
}

In this example, the function is using the placeholder type T to represent the type of the values being swapped. The keyword 'inout' is used to indicate that the values will be modified directly. Let's see how to use this function with different types:

var a = 5
var b = 10
swapTwoValues(&a, &b)
print("a is now \(a), and b is now \(b)")
 
var c = "hello"
var d = "world"
swapTwoValues(&c, &d)
print("c is now \(c), and d is now \(d)")

In this example, we passed in two variables of different types, an integer and a string, and the function successfully swaps them.

Generic Type

A generic type is a structure or class that can work with any type. Let's create a generic type that represents a stack:

struct Stack<Element> {
    var items = [Element]()
 
    mutating func push(_ item: Element) {
        items.append(item)
    }
 
    mutating func pop() -> Element? {
        if items.isEmpty {
            return nil
        } else {
            return items.removeLast()
        }
    }
}

In this example, the stack is defined using the placeholder type Element to represent the type of the items in the stack. The methods push and pop are mutating methods because they modify the items in the stack directly.

Let's see how to use this generic type with different types:

var intStack = Stack<Int>()
intStack.push(1)
intStack.push(2)
intStack.push(3)
print(intStack.pop())
print(intStack.pop())
 
var stringStack = Stack<String>()
stringStack.push("hello")
stringStack.push("world")
print(stringStack.pop())

In this example, we created two stacks using different types, an integer and a string, and successfully pushed and popped items from each stack.

Conclusion

Generics allow you to write flexible and reusable code that can work with any type, as long as that type meets the required criteria. It is an advanced Swift feature used heavily in iOS development and can greatly improve the efficiency of your code.