定义泛型函数:
func swapTwoValues<T>(_ a: inout T, _ b: inout T) { let temporatyA = a a = b b = temporatyA}
定义泛型类型:
struct Stack<Element> { var elements = [Element]() mutating func push(_ element: Element) { elements.append(element) } mutating func pop() -> Element { return elements.removeLast() }}
外界使用push如下:
var stackOfString = Stack<String>()stackOfString.push("uno")stackOfString.push("dos")stackOfString.push("tres")stackOfString.push("custro")
图解如下:
在上面基础上,外界使用pop如下:
var stackOfString = Stack<String>()stackOfString.pop()
图解如下:
扩展泛型类型
当你扩展一个泛型类型的时候,不需要在扩展的定义中提供类型形式参数列表。原始类型定义的类型形式参数列表在扩展体里面仍然有效,并且原始类型形式参数列表名称也用于扩展类型形式参数。
struct Stack<Element> { var elements = [Element]() mutating func push(_ element: Element) { elements.append(element) } mutating func pop() -> Element { return elements.removeLast() }}
extension Stack { var topItem: Element? { return elements.last }}
Where子句
泛型函数中使用where语句
protocol Container { associatedtype ItemType mutating func append(_ item: ItemType) var count: Int { get } subscript(i: Int) -> ItemType { get }}
func allItemsMatch<C1: Container, C2: Container>(someContainer: C1, anotherContainer: C2) -> Bool where C1.ItemType == C2.ItemType, C1.ItemType: Equatable { // 首先检查元素个数是否相等 if someContainer.count != anotherContainer.count { return false } // 然后检查每一个元素是否相等 for i in 0..<someContainer.count { if someContainer[i] != anotherContainer[i] { return false } } // 当所有都匹配成功后,返回ture return true}
该例中的约束如下:
上面?这四点意味着下面?这四点:
泛型类型中使用where语句
可以在扩展中使用泛型的where子句
struct Stack<Element> { var elements = [Element]() mutating func push(_ element: Element) { elements.append(element) } mutating func pop() -> Element { return elements.removeLast() }}
extension Stack where Element: Equatable { func isTop(item: Element) -> Bool { guard let lastItem = elements.last else { return false } return item == lastItem }}
这里的where语句表示的是:只有当Stack中的元素类型是遵循Equatable协议的时候,才会添加isTop方法。
泛型下标
在Swift中,下标也是支持泛型的。你可以在subscript后面用尖括号来写类型占位符,你还可以在下标代码块花括号前写泛型where分句。
protocol Container { associatedtype ItemType mutating func append(_ item: ItemType) var count: Int { get } subscript(i: Int) -> ItemType { get }}
extension Container { subscript<Indices: Sequence>(indices: Indices) -> [ItemType] where Indices.Iterator.Element == Int { var result = [ItemType]() for index in indices { result.append(self[index]) } return result }}
以上。