Swift 4语言提供了泛型(Generic
)功能来编写灵活且可重用的函数和类型。 泛型用于避免重复并提供抽象。 Swift 4标准库使用泛型代码构建。 Swift 4中的数组和字典类型属于泛型集合。 使用数组和字典,数组可定义为保存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)")
当使用playground运行上述程序时,得到以下结果 -
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)")
当使用playground运行上述程序时,得到以下结果 -
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>
作为泛型类型参数名称。 但是,类型参数(如数组和字典)也可以命名为key,value
以标识它们属于字典类型。
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()
当使用playground运行上述程序时,得到以下结果 -
[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).") }
当使用playground运行上述程序时,得到以下结果 -
["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)")
当使用playground运行上述程序时,得到以下结果 -
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允许通过关键字associatedtype
在协议定义内声明关联类型。
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)
当使用playground运行上述程序时,得到以下结果 -
[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)
当使用playground运行上述程序时,得到以下结果 -
[Swift 4] [Swift 4, Generics] [Swift 4, Generics, Where Clause] [Swift 4, Generics, Where Clause]