Примеры использования generics в Swift
Что проверяют
Пишете ли вы обобщённый код сами или только пользуетесь чужим. Generics в Swift не украшение: на них держатся коллекции, Optional, Result и любой аккуратный сетевой слой, поэтому вопрос быстро уходит вглубь, к ограничениям и к some против any.
Как отвечать
Покажите три уровня применения.
struct Box<Item> {
var value: Item
}
func request<T: Decodable>(_ endpoint: Endpoint) async throws -> T {
let (data, _) = try await session.data(for: endpoint.urlRequest)
return try decoder.decode(T.self, from: data)
}
extension Array where Element: Numeric {
var total: Element { reduce(0, +) }
}Дальше назовите живые места в приложении: единый сетевой клиент, который возвращает нужную модель без приведения типов, типобезопасное переиспользование ячеек таблицы, обёртки над хранилищем, обёртки свойств.
Отдельно проговорите ограничения: параметр без требований почти бесполезен, сила в where и в требованиях протоколов. И упомяните протоколы с ассоциированными типами: это не обобщённый протокол, а параметр, который выбирает реализация. Отсюда разница между some Collection, где конкретный тип известен компилятору, и any Collection, где тип спрятан за оболочкой и часть операций недоступна.
Где спотыкаются
Путают обобщение и Any. Второе стирает тип и заставляет приводить его обратно с риском падения, а параметр типа сохраняется на компиляции, и приводить нечего.
Второе: не понимают, откуда берётся тип в функции вроде request. Он выводится из места вызова, и без аннотации результата компилятор честно говорит, что вывести параметр не смог. Это первая боль всех, кто пишет обобщённый сетевой слой.
Третье: ждут от обобщений наследования. Тип Box<Cat> не является Box<Animal>, даже если Cat наследник Animal, и попытка сложить их в один массив упирается ровно в это правило.