generics и ассоциированные типы — зачем?
Суть
Дженерики позволяют написать алгоритм или контейнер один раз для любого типа, сохранив статическую проверку типов. Ограничения (T: Comparable, where) задают, что от типа требуется. В протоколах роль «параметра типа» играет associatedtype: протокол описывает семейство типов, а конкретный тип элемента определяет каждый конформер.
func largest<T: Comparable>(_ xs: [T]) -> T? { xs.max() } // любой тип
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
Продолжение ответа с кодом и уточняющими вопросами интервьюера — в приложении DevPrep.
Полный ответ — в DevPrep