Язык Swift 4 предоставляет «универсальные» функции для написания гибких и многократно используемых функций и типов. Обобщения используются, чтобы избежать дублирования и обеспечить абстракцию. Стандартные библиотеки Swift 4 построены с использованием универсального кода. Типы Swift 4s ‘Arrays’ и ‘Dictionary’ относятся к общим коллекциям. С помощью массивов и словарей массивы определяются для хранения значений «Int» и «String» или любых других типов.
func exchange(a: inout Int, b: inout Int) { let temp = a a = b b = temp } var numb1 = 100 var numb2 = 200 print("Before Swapping values are: \(numb1) and \(numb2)") exchange(a: &numb1, b: &numb2) print("After Swapping values are: \(numb1) and \(numb2)")
Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —
Before Swapping values are: 100 and 200 After Swapping values are: 200 and 100
Общие функции: параметры типа
Общие функции могут использоваться для доступа к любому типу данных, например, «Int» или «String».
func exchange<T>(a: inout T, b: inout T) { let temp = a a = b b = temp } var numb1 = 100 var numb2 = 200 print("Before Swapping Int values are: \(numb1) and \(numb2)") exchange(a: &numb1, b: &numb2) print("After Swapping Int values are: \(numb1) and \(numb2)") var str1 = "Generics" var str2 = "Functions" print("Before Swapping String values are: \(str1) and \(str2)") exchange(a: &str1, b: &str2) print("After Swapping String values are: \(str1) and \(str2)")
Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —
Before Swapping Int values are: 100 and 200 After Swapping Int values are: 200 and 100 Before Swapping String values are: Generics and Functions After Swapping String values are: Functions and Generics
Функция exchange () используется для обмена значениями, которые описаны в приведенной выше программе, а <T> используется в качестве параметра типа. В первый раз вызывается функция exchange (), которая возвращает значения «Int», а второй вызов функции exchange () возвращает значения «String». Несколько угловых параметров могут быть включены в угловые скобки, разделенные запятыми.
Параметры типа именуются как пользовательские, чтобы знать назначение параметра типа, который он содержит. Swift 4 предоставляет <T> в качестве имени параметра универсального типа. Однако параметры типа, такие как массивы и словари, также могут быть названы в качестве ключа, значения, чтобы определить, что они принадлежат к типу «Словарь».
struct TOS<T> { var items = [T]() mutating func push(item: T) { items.append(item) } mutating func pop() -> T { return items.removeLast() } } var tos = TOS<String>() tos.push(item: "Swift 4") print(tos.items) tos.push(item: "Generics") print(tos.items) tos.push(item: "Type Parameters") print(tos.items) tos.push(item: "Naming Type Parameters") print(tos.items) let deletetos = tos.pop()
Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —
[Swift 4] [Swift 4, Generics] [Swift 4, Generics, Type Parameters] [Swift 4, Generics, Type Parameters, Naming Type Parameters]
Расширение универсального типа
Расширение свойства стека для определения вершины элемента включено с ключевым словом extension.
struct TOS<T> { var items = [T]() mutating func push(item: T) { items.append(item) } mutating func pop() -> T { return items.removeLast() } } var tos = TOS<String>() tos.push(item: "Swift 4") print(tos.items) tos.push(item: "Generics") print(tos.items) tos.push(item: "Type Parameters") print(tos.items) tos.push(item: "Naming Type Parameters") print(tos.items) extension TOS { var first: T? { return items.isEmpty ? nil : items[items.count - 1] } } if let first = tos.first { print("The top item on the stack is \(first).") }
Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —
["Swift 4"] ["Swift 4", "Generics"] ["Swift 4", "Generics", "Type Parameters"] ["Swift 4", "Generics", "Type Parameters", "Naming Type Parameters"] The top item on the stack is Naming Type Parameters.
Тип Ограничения
Язык Swift 4 позволяет «ограничениям типа» указывать, наследуется ли параметр типа от определенного класса, или обеспечивать стандарт соответствия протокола.
func exchange<T>(a: inout T, b: inout T) { let temp = a a = b b = temp } var numb1 = 100 var numb2 = 200 print("Before Swapping Int values are: \(numb1) and \(numb2)") exchange(a: &numb1, b: &numb2) print("After Swapping Int values are: \(numb1) and \(numb2)") var str1 = "Generics" var str2 = "Functions" print("Before Swapping String values are: \(str1) and \(str2)") exchange(a: &str1, b: &str2) print("After Swapping String values are: \(str1) and \(str2)")
Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —
Before Swapping Int values are: 100 and 200 After Swapping Int values are: 200 and 100 Before Swapping String values are: Generics and Functions After Swapping String values are: Functions and Generics
Связанные типы
Swift 4 позволяет объявлять связанные типы в определении протокола по ключевому слову «relatedtype».
protocol Container { associatedtype ItemType mutating func append(item: ItemType) var count: Int { get } subscript(i: Int) -> ItemType { get } } struct TOS<T>: Container { // original Stack<T> implementation var items = [T]() mutating func push(item: T) { items.append(item) } mutating func pop() -> T { return items.removeLast() } // conformance to the Container protocol mutating func append(item: T) { self.push(item: item) } var count: Int { return items.count } subscript(i: Int) -> T { return items[i] } } var tos = TOS<String>() tos.push(item: "Swift 4") print(tos.items) tos.push(item: "Generics") print(tos.items) tos.push(item: "Type Parameters") print(tos.items) tos.push(item: "Naming Type Parameters") print(tos.items)
Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —
[Swift 4] [Swift 4, Generics] [Swift 4, Generics, Type Parameters] [Swift 4, Generics, Type Parameters, Naming Type Parameters]
Где пункты
Ограничения типа позволяют пользователю определять требования к параметрам типа, связанным с универсальной функцией или типом. Для определения требований к связанным типам предложения ‘where’ объявляются как часть списка параметров типа. Ключевое слово ‘where’ помещается сразу после списка параметров типа, за которым следуют ограничения связанных типов, отношения равенства между типами и связанными типами.
protocol Container { associatedtype ItemType mutating func append(item: ItemType) var count: Int { get } subscript(i: Int) -> ItemType { get } } struct Stack<T>: Container { // original Stack<T> implementation var items = [T]() mutating func push(item: T) { items.append(item) } mutating func pop() -> T { return items.removeLast() } // conformance to the Container protocol mutating func append(item: T) { self.push(item: item) } var count: Int { return items.count } subscript(i: Int) -> T { return items[i] } } func allItemsMatch< C1: Container, C2: Container where C1.ItemType == C2.ItemType, C1.ItemType: Equatable> (someContainer: C1, anotherContainer: C2) -> Bool { // check that both containers contain the same number of items if someContainer.count != anotherContainer.count { return false } // check each pair of items to see if they are equivalent for i in 0..<someContainer.count { if someContainer[i] != anotherContainer[i] { return false } } // all items match, so return true return true } var tos = Stack<String>() tos.push(item: "Swift 4") print(tos.items) tos.push(item: "Generics") print(tos.items) tos.push(item: "Where Clause") print(tos.items) var eos = ["Swift 4", "Generics", "Where Clause"] print(eos)
Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —