Generics - это механизм, который позволяет писать универсальные функции и типы, работающие с любыми типами данных, сохраняя при этом полную типобезопасность.
Зачем нужны дженерики?
- Уменьшают дублирование кода: больше не нужно писать отдельные функции для Int, Float и других типов - один обобщённый вариант заменит их все.
- Обеспечивают типобезопасность: компилятор проверяет типы на этапе компиляции, предотвращая ошибки в рантайме.
- Повышают переиспользуемость: один алгоритм можно применять к разным типам данных без изменений.
Как работают дженерики?
Дженерики используют параметры типа (обычно обозначаются
, и т. д.), которые заменяются конкретными типами при компиляции.
Пример использования:
func plusValue(first: T, second: T) -> T {
return first + second
}
let a = 5
let b = 10
print(plusValue(first: a, second: b)) // 15
let c = 0.5
let d = 3.0
print(plusValue(first: c, second: d)) // 3.0
//
struct Stack {
private var elements = [Element]()
mutating func push(_ element: Element) {
elements.append(element)
}
mutating func pop() -> Element? {
return elements.popLast()
}
}
var intStack = Stack()
intStack.push(1)
var stringStack = Stack()
stringStack.push("Swift")
Ограничения дженериков:
Иногда нужно указать, что тип T должен соответствовать определённым требованиям. Для этого используют протоколы:
func plusValue(first: T, second: T) -> T {
return first + second
}
Здесь T должен являться числом (Numeric), иначе код не скомпилируется.