Swift - Дженерики
Язык Swift 4 предоставляет «общие» функции для написания гибких и многоразовых функций и типов. Обобщения используются, чтобы избежать дублирования и обеспечить абстракцию. Стандартные библиотеки Swift 4 построены с использованием универсального кода. Типы Swift 4s «Массивы» и «Словарь» относятся к общим коллекциям. С помощью массивов и словарей массивы определяются для хранения значений «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> как имя параметра универсального типа. Однако параметры типа, такие как массивы и словари, также могут быть названы ключом, значением, чтобы идентифицировать их принадлежность к типу Dictionary.
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 позволяет объявлять связанные типы внутри определения протокола с помощью ключевого слова connectedtype.
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)
Когда мы запускаем вышеуказанную программу с помощью игровой площадки, мы получаем следующий результат:
[Swift 4]
[Swift 4, Generics]
[Swift 4, Generics, Where Clause]
[Swift 4, Generics, Where Clause]