Ограничение ассоциированных типов
Ограничивайте ассоциированные типы в обобщённых контекстах.
«Ограничение ассоциированных типов» — бесплатный урок Swift Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Swift Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Swift Academy содержит 4 уроков всего.
Итоги по связанным типам
Протокол может объявить связанный тип с помощью associatedtype — это заполнитель, которому соответствующий тип назначает конкретное значение. Классический пример — Element в протоколе контейнера.
protocol Container {
associatedtype Item
var count: Int { get }
func item(at i: Int) -> Item
}Соответствие с конкретным типом
Соответствующий тип фиксирует связанный тип, который часто выводится из способа его использования.
protocol Container {
associatedtype Item
func item(at i: Int) -> Item
}
struct IntBox: Container {
let values: [Int]
func item(at i: Int) -> Int { values[i] }
}
print(IntBox(values: [10, 20]).item(at: 1))Ограничение связанного типа
Добавьте ограничение прямо в объявление: associatedtype Item: Comparable требует, чтобы тип элемента каждого соответствующего типа поддерживал сравнение.
protocol Sorted {
associatedtype Item: Comparable
var items: [Item] { get }
}
struct Nums: Sorted { let items: [Int] }
print(Nums(items: [3, 1, 2]).items.sorted())Использование ограничения
Поскольку связанный тип ограничен, расширения протокола могут полагаться на эту возможность.
protocol Sorted {
associatedtype Item: Comparable
var items: [Item] { get }
}
extension Sorted {
var smallest: Item? { items.min() }
}
struct Nums: Sorted { let items: [Int] }
print(Nums(items: [5, 2, 8]).smallest!)where для associatedtype
Swift также позволяет использовать условие where для связанного типа, чтобы связать его с другим связанным или вложенным типом.
protocol Sequence2 {
associatedtype Element
associatedtype Iterator: IteratorProtocol where Iterator.Element == Element
}Ограничение другим протоколом
Для связанного типа можно потребовать соответствия определённому Вами протоколу, постепенно добавляя поведение.
protocol HasName { var name: String { get } }
protocol Registry {
associatedtype Entry: HasName
var entries: [Entry] { get }
}
struct User: HasName { let name: String }
struct Users: Registry { let entries: [User] }
print(Users(entries: [User(name: "Ada")]).entries[0].name)Несколько связанных типов
Протокол может объявлять несколько связанных типов, каждый со своими независимыми ограничениями.
protocol Mapping {
associatedtype Key: Hashable
associatedtype Value
func value(for k: Key) -> Value?
}
struct Phonebook: Mapping {
let data: [String: Int]
func value(for k: String) -> Int? { data[k] }
}
print(Phonebook(data: ["x": 1]).value(for: "x")!)Связанный тип по умолчанию
Связанному типу можно задать значение по умолчанию с помощью =. Оно используется, если соответствующий тип не указывает другое значение.
protocol Producer {
associatedtype Output = String
func make() -> Output
}
struct Hello: Producer {
func make() -> String { "hi" }
}
print(Hello().make())Ограничения открывают доступ к обобщённым алгоритмам
Имея ограниченный связанный тип, расширение протокола может реализовать полноценные алгоритмы, общие для всех соответствующих типов.
protocol Scored {
associatedtype Score: Comparable
var scores: [Score] { get }
}
extension Scored {
var best: Score? { scores.max() }
}
struct Game: Scored { let scores: [Int] }
print(Game(scores: [10, 40, 25]).best!)Ограничения равенства типов в расширениях
За пределами протокола можно дополнительно ограничить связанный тип при расширении протокола.
protocol Box2 {
associatedtype Content
var content: Content { get }
}
extension Box2 where Content == Int {
var doubled: Int { content * 2 }
}
struct IB: Box2 { let content: Int }
print(IB(content: 7).doubled)Зачем устанавливать ограничения
Ограничение связанных типов позволяет протоколам оставаться обобщёнными и при этом мощными: это обещание, на которое могут рассчитывать расширение и вызывающий код.
protocol Listy {
associatedtype E: Equatable
var elements: [E] { get }
}
extension Listy {
func has(_ x: E) -> Bool { elements.contains(x) }
}
struct L: Listy { let elements: [String] }
print(L(elements: ["a", "b"]).has("b"))Проверка понимания
Проверьте, насколько хорошо Вы поняли ограничения связанных типов.
Итоги
Вы можете напрямую ограничивать связанные типы (associatedtype Item: Comparable), связывать их условиями where, требовать соответствия протоколу, задавать значения по умолчанию с помощью =, объявлять несколько связанных типов и уточнять их в расширениях. Ограничения позволяют расширениям протоколов реализовывать общие алгоритмы с проверкой типов.
Часто задаваемые вопросы
Урок «Ограничение ассоциированных типов» бесплатный?
Да — полный текст урока «Ограничение ассоциированных типов» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Swift Academy, подпишись на CoddyKit PRO. Курс Swift Academy содержит 4 уроков всего.
Чему я научусь в уроке «Ограничение ассоциированных типов»?
Ограничивайте ассоциированные типы в обобщённых контекстах. Ты практикуешь Swift Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Swift Academy?
Предыдущий опыт не требуется. Swift Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Ограничение ассоциированных типов»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Swift Academy?
Да. Каждый урок Swift Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Ограничения параметров типов
- Предложения where в функциях
- Ограничение ассоциированных типов
- Обобщённые индексы и расширения