Skip to content
Swift

Generics

Write type-parameterized functions and types with protocol constraints.

By EZ4Code Team
genericsconstraint

Code

import Foundation

// Generic function
func maxOf<T: Comparable>(_ a: T, _ b: T) -> T {
    return a > b ? a : b
}
print(maxOf(3, 5))
print(maxOf("pear", "apple"))

// Generic stack
struct Stack<Element> {
    private var items: [Element] = []
    var count: Int { items.count }
    mutating func push(_ x: Element) { items.append(x) }
    mutating func pop() -> Element? { items.popLast() }
}

var s = Stack<Int>()
s.push(1); s.push(2)
print(s.pop() ?? 0)

// Generic function with multiple constraints
func paired<T, U>(_ a: T, _ b: U) -> (T, U) { (a, b) }
print(paired(1, "x"))

// Associated type constrained by a protocol
protocol Repository {
    associatedtype Entity: Identifiable
    func find(_ id: Entity.ID) -> Entity?
}

struct User: Identifiable { let id: Int; let name: String }
struct UserRepo: Repository {
    typealias Entity = User
    func find(_ id: Int) -> User? { User(id: id, name: "u\(id)") }
}

print(UserRepo().find(7)?.name ?? "none")

Explanation

Generics write one implementation that works for any type while preserving compile-time type safety. Constraints like Comparable or Identifiable restrict type arguments to those that conform to a protocol. Associated types let protocols declare a placeholder type that conforming types fill in, enabling type-safe abstractions like repositories.

More Swift Snippets