泛型可以使我们在程序代码中定义一些可变的部分,在运行的时候指定。使用泛型可以最大限度的重用代码、保护类型的安全以及提高性能。在swift集合中。数组、set和字典都是泛型集合。
泛型函数
一个简单的泛型函数代码示例:
func isEquals<T>(a: T, b: T) -> Bool {
return (a == b)
}
T被称为占位符,函数在每次调用的时候传入示例类型才能决定T所代表的类型。
使用泛型函数
上述代码在使用时会发生变异错误,这是因为并不是所有的类型都具有可比性,T必须是遵从Comparable协议的类型。所以代码修改如下:
func isEquals<T:Comparable>(a: T, b: T) -> Bool {
return (a == b)
}
这种在泛型占位符后面加上协议类型的表示方式称为泛型约束。它能够替换T的类型。
多参数泛型
多参数泛型就是提供多个占位符。多个占位符之间使用“,”隔开。
func isEquals<T, U>(a: T, b: U) -> Bool {...}
占位符替代返回值类型
func isEquals<T, U>(a: T, b: U) -> T {...}
泛型类型
泛型不仅可以应用在函数中,还可以应用于类、结构体和枚举等类型定义。这些类型就是泛型类型。泛型类型一般都是与集合有关的类型。如数组、字典等。
struct Queue<T> {
var items = [T]()
mutating func queue(item: T) {
items.append(item)
}
mutating func dequeue() -> T? {
if items.isEmpty {
return nil
}
return items.remove(at: 0)
}
}
var queue = Queue<Int>()
queue.queue(item: 10)
print(queue.dequeue()!)
泛型扩展
泛型类型还可以支持扩展。泛型扩展和其他类型的扩展没有区别
struct Queue<T> {
var items = [T]()
mutating func queue(item: T) {
items.append(item)
}
mutating func dequeue() -> T? {
if items.isEmpty {
return nil
}
return items.remove(at: 0)
}
}
extension Queue {
func peek(position: Int) -> T? {
if position < 0 || position > items.count {
return nil
} else {
return items[position]
}
}
}
var queue = Queue<Int>()
queue.queue(item: 10)
print(queue.peek(position: 0)!)
print(queue.dequeue()!)