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 is a powerful feature of Swift that allows you to write functions, classes, and structures that can work with any type. This is achieved by using placeholders for types that are only defined when the function, class, or structure is actually used.

Example: Generic Function

Let's take a look at a generic function that swaps two values of any type:

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

The `<T>` placeholder indicates that this function can work with any type, and `inout` parameters allow it to modify the values passed in. Here's how you can use this function:

var a = 10
var b = 20
swap(&a, &b)
// a is now 20, b is now 10

var c = "Hello"
var d = "World"
swap(&c, &d)
// c is now "World", d is now "Hello"

Example: Generic Type

You can also use generics to define generic types, which can be used with any specific type or a type that conforms to a specific protocol. Here's an example of a generic type:

struct Queue<T> {
    private var items = [T]()

    mutating func enqueue(_ item: T) {
        items.append(item)
    }

    mutating func dequeue() -> T? {
        if items.isEmpty {
            return nil
        }
        return items.removeFirst()
    }
}

The `<T>` placeholder indicates that this type can work with any type. Here's how you can use this type:

var queue = Queue<Int>()
queue.enqueue(10)
queue.enqueue(20)
queue.enqueue(30)
print(queue.dequeue()) // prints Optional(10)
print(queue.dequeue()) // prints Optional(20)
print(queue.dequeue()) // prints Optional(30)
print(queue.dequeue()) // prints nil

As you can see, `Queue<Int>` is a type that can work with integers. You can also use `Queue<String>` or any other type that conforms to the `Equatable` protocol.

Conclusion

Generics is a powerful feature of Swift that allows you to write generic functions, classes, and structures that can work with any type. This can make your code more flexible and reusable. You can use placeholders for types and define generic types that can work with any specific type or a type that conforms to a specific protocol.