DevPrep

All topics › Modern Swift

generics and associated types — why?

Middle PRO

The idea

Generics let you write an algorithm or container once for any type while keeping static type checking. Constraints (T: Comparable, where) state what the type must provide. In protocols the "type parameter" role is played by associatedtype: the protocol describes a family of types, and each conformer decides the concrete element type.

func largest<T: Comparable>(_ xs: [T]) -> T? { xs.max() }   // any type

protocol Repository<Entity> {
    associatedtype Entity: Identifiable
    func fetch(id: Entity.ID) async throws -> Entity?
}

struct Cache<Key: Hashable, Value> {
    private var dict: [Key: Value] = [:]
    subscript(key: Key) -> Value? {
        get { dict[key] }
        set { dict[key] = newValue }
    }
}

func ids<R: Repository>(_ repo: R, _ entities: [R.Entity]) -> [R.Entity.ID]
    where R.Entity.ID == Int {
    entities.map(\.id)
}
print(largest([3, 1, 2]) ?? 0)   // 3

The rest of this answer, with code and interview follow-ups, is in the DevPrep app.

Read the full answer in DevPrep

Practice this before your interview

DevPrep turns these answers into one-minute challenges: what does this code print, find the bug, mock interviews. One challenge a day.

Get DevPrep on the App Store