Ответ
Ограничения (constraints) для generic-параметров указывают, какими свойствами должен обладать конкретный тип. Это делается с помощью протоколов, классов или требований равенства типов.
1. Базовый синтаксис (после двоеточия :)
Указывает, что тип T должен соответствовать одному протоколу или быть подклассом определенного класса.
// T должен соответствовать протоколу Comparable
func findMax<T: Comparable>(_ a: T, _ b: T) -> T {
return a > b ? a : b
}
// T должен быть подклассом UIView
func configureView<T: UIView>(_ view: T) where T: Configurable {
view.configure()
}
2. Уточнение с помощью where-предложения
Позволяет задавать более сложные условия, особенно когда ограничений несколько или они касаются нескольких параметров.
// T должен соответствовать и Numeric, и Comparable
func processNumbers<T>(_ numbers: [T]) -> T where T: Numeric, T: Comparable {
return numbers.sorted().last!
}
// Два параметра, Item которых должен быть одного и того же Equatable типа
func areItemsEqual<C1: Container, C2: Container>(_ c1: C1, _ c2: C2) -> Bool
where C1.Item == C2.Item, C1.Item: Equatable {
guard let item1 = c1.items.first, let item2 = c2.items.first else { return false }
return item1 == item2
}
3. Ограничения на ассоциированные типы в протоколах
protocol Container {
associatedtype Item
var items: [Item] { get set }
}
// Расширение добавляет метод только для Container, у которых Item — Equatable
extension Container where Item: Equatable {
func contains(_ item: Item) -> Bool {
return items.contains(item)
}
}
// Расширение для Container, у которых Item — конкретный тип (например, String)
extension Container where Item == String {
func concatenated() -> String {
return items.joined()
}
}
Основные виды ограничений:
- Соответствие протоколу:
T: SomeProtocol - Наследование класса:
T: SomeClass - Равенство типов:
T == SomeSpecificTypeилиT.Item == U.Item - Составные условия: Через
where T: P1, T: P2илиwhere T: P1, U: P2.
Ограничения делают generics типобезопасными, позволяя компилятору гарантировать, что с типами можно выполнять только допустимые операции.