【Swift】泛型

288 阅读1分钟

template vs generic

  • 模版是C++泛型编程的基础

  • 泛型更来之一种编程思路

swift 中的泛型

  • 和c++ 中差不多<>

  • 扩展泛型类型

struct Stack<Element> {
    var items = [Element]()
    mutating func push(_ item: Element){
        items.append(item)
    }
    
    mutating func pop() -> Element {
        return items.removeLast()
    }
}

var stackOfStrings = Stack<String>()
stackOfStrings.push("uno")
stackOfStrings.push("uno")
stackOfStrings.push("uno")
stackOfStrings.push("uno")

let t = stackOfStrings.pop()
  • 类型约束
    • 例如 Dictionary类型在可以用于字典中键的类型上设置一个限制。如字典描中的描述,字典键的类型必须是可哈希的。
    • 类型约束语法
func someFunction<T: someClass, U: someProtocal> {
    // function body
}
func firstIndex<T: Equatable>(of valueOfFind: T, in array: [T]) -> Int? {
    for (index, value) in array.enumerated() {
        if value == valueOfFind {
            return index
        }
    }
    return nil
}

let names = ["zhangsan", "wangwu", "liliu"]
print(firstIndex(of: "liliu", in: names))
  • 关联类型

定义一个协议时,有时在协议定义里声明一个或多个关联类型是很有用的。关联类型给协议中用到一个占位符名称。直到采纳协议时,才指定用于该关联类型的实际类型。关联类型通过associatedtype关键字指定。

protocol Container {
    associatedtype ItemType
    mutating func append(_ item: ItemType)
    var count: Int { get }
    subscript(i: Int) -> ItemType { get }
}

struct IntStack: Container {
    var items = [Int] ()
    
    typealias ItemType = Int
    
    mutating func append(_ item: Int) {
        items.append(item)
    }
    
    var count: Int {
        return items.count
    }
    
    subscript(i: Int) -> Int {
        return items[i]
    }
}

var intStack = IntStack()
intStack.append(1)
intStack.append(2)
print(intStack.count)
print(intStack[0])
  • where 子句
func allItemsMatch<C1: Container, C2: Container>(container1: C1, container2: C2) -> Bool where C1.ItemType == C2.ItemType, C1.ItemType: Equatable{
    
    if container1.count != container2.count {
        return false
    }
    
    for i in 0..<container1.count {
        if container1[i] != container2[i] {
            return false
        }
    }
    return true
}
  • 泛型下标
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
    }
}

print(intStack[[0, 1]])