generics and associated types — why?
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