泛型代码可以让你写出根据自我需求定义、适用于任何类型的,灵活且可重用的函数和类型。它可以让你避免重复的代码,用一种清晰和抽象的方式来表达代码的意图。
泛型是 Swift 强大特征中的其中一个,许多 Swift 标准库是通过泛型代码构建出来的。事实上,泛型的使用贯穿了整本语言手册,只是你没有发现而已。例如,Swift 的数组和字典类型都是泛型集。你可以创建一个Int数组,也可创建一个String数组,或者甚至于可以是任何其他 Swift 的类型数据数组。同样的,你也可以创建存储任何指定类型的字典(dictionary),而且这些类型可以是没有限制的。
泛型所解决的问题
这里是一个标准的,非泛型函数swapTwoInts,用来交换两个Int值:
泛型函数:类型参数
泛型函数可以访问任何数据类型,如:'Int' 或 'String'.
var numb1 = 100
var numb2 = 200
println("Before Swapping Int values are: /(numb1) and /(numb2)")
exchange(&numb1, &numb2)
println("After Swapping Int values are: /(numb1) and /(numb2)")
var str1 = "Generics"
var str2 = "Functions"
println("Before Swapping String values are: /(str1) and /(str2)")
exchange(&str1, &str2)
println("After Swapping String values are: /(str1) and /(str2)")
Before Swapping Int values are: 100 and 200After Swapping Int values are: 200 and 100Before Swapping String values are: Generics and FunctionsAfter Swapping String values are: Functions and Generics
函数 exchange()用于交换其在上述方案中描述和<T>被用作类型参数值。这是第一次,函数 exchange()被调用返回Int值,第二次调用函数 exchange()将返回String值。多参数类型可包括用逗号分隔在尖括号内。
类型参数被命名为用户定义来了解拥有类型参数的目的。 Swift 提供<T>作为泛型类型参数的名字。 但是型像数组和字典参数也可以命名为键,值,以确定它们输入属于“字典”。
泛型类型
var tos = TOS<String>()
tos.push("Swift")
println(tos.items)
tos.push("Generics")
println(tos.items)
tos.push("Type Parameters")
println(tos.items)
tos.push("Naming Type Parameters")
println(tos.items)
let deletetos = tos.pop()
[Swift][Swift, Generics][Swift, Generics, Type Parameters][Swift, Generics, Type Parameters, Naming Type Parameters]
扩展泛型类型
扩展堆栈属性要知道该项目的顶部包含在“extension” 关键字。
mutating func pop() -> T {
return items.removeLast()
}
}
var tos = TOS<String>()
tos.push("Swift")
println(tos.items)
tos.push("Generics")
println(tos.items)
tos.push("Type Parameters")
println(tos.items)
tos.push("Naming Type Parameters")
println(tos.items)
extension TOS {
var first: T? {
return items.isEmpty ? nil : items[items.count - 1]
}
}
if let first = tos.first {
println("The top item on the stack is /(first).")
}
[Swift][Swift, Generics][Swift, Generics, Type Parameters][Swift, Generics, Type Parameters, Naming Type Parameters]
在堆栈顶部的项目命名类型参数。
类型约束
Swift 语言允许“类型约束”指定类型参数是否从一个特定的类继承,或者确保协议一致性标准。
var numb1 = 100
var numb2 = 200
println("Before Swapping Int values are: /(numb1) and /(numb2)")
exchange(&numb1, &numb2)
println("After Swapping Int values are: /(numb1) and /(numb2)")
var str1 = "Generics"
var str2 = "Functions"
println("Before Swapping String values are: /(str1) and /(str2)")
exchange(&str1, &str2)
println("After Swapping String values are: /(str1) and /(str2)")
Before Swapping Int values are: 100 and 200After Swapping Int values are: 200 and 100Before Swapping String values are: Generics and FunctionsAfter Swapping String values are: Functions and Generics
关联类型
Swift 允许相关类型,并可由关键字“typealias”协议定义内部声明。
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)
}
var count: Int {
return items.count
}
subscript(i: Int) -> T {
return items[i]
}
}
var tos = TOS<String>()
tos.push("Swift")
println(tos.items)
tos.push("Generics")
println(tos.items)
tos.push("Type Parameters")
println(tos.items)
tos.push("Naming Type Parameters")
println(tos.items)
[Swift][Swift, Generics][Swift, Generics, Type Parameters][Swift, Generics, Type Parameters, Naming Type Parameters]
Where 子句
类型约束使用户能够定义与泛型函数或类型相关联的类型的参数要求。用于定义相关类型的 'where' 子句声明为类型参数列表的一部分要求。 “where”关键字类型参数后面类型和相关类型之间的相关类型的限制,平等关系的列表后放置。
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)
}
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("Swift")
println(tos.items)
tos.push("Generics")
println(tos.items)
tos.push("Where Clause")
println(tos.items)
var eos = ["Swift", "Generics", "Where Clause"]
println(eos)
[Swift][Swift, Generics][Swift, Generics, Where Clause][Swift, Generics, Where Clause]
新闻热点
疑难解答
图片精选