【学习】重学Swift5-泛型

七、泛型

func swapTwoInts(_ a:inout Int, _ b:inout Int) {
    let temp = a
    a = b
    b = temp
}

func swaoTwoValues<T>(_ a:inout T, _ b:inout T) {
    let temp = a
    a = b
    b = temp
}

var a = 13, b = 12
swapTwoInts(&a, &b)
print(a, b)

var aStr = "12", bStr = "333"
//swapTwoInts(&aStr, &bStr)

swaoTwoValues(&a, &b)
print(a, b)
swaoTwoValues(&aStr, &bStr)
print(aStr, bStr)
// 上面的🌰中,swapTwoInts只能交换Int类型的值,而后面声明的泛型swaoTwoValues可以交换不同类型的值,更简洁

struct Stack<Element> {
    var items = [Element]()
    
    mutating func push(_ item: Element) {
        items.append(item)
    }
    
    mutating func pop() -> Element {
        return items.removeLast()
    }
}
// 初始化的时候类型不能省略Stack<String>()
var stackOfStrings = Stack<String>()
stackOfStrings.push("ddd")
stackOfStrings.push("jdieji")
stackOfStrings.push("d")
stackOfStrings.pop()
// 上面的🌰中,声明了一个泛型栈

//当你扩展一个泛型类型时,不需要在扩展的定义中提供类型形式参数列表。原始类型定义的类型形式参数列表在扩展体里仍然有效,并且原始类型形式参数列表名称也用于扩展类型形式参数。
extension Stack {
    var topItem: Element? {
        return items.isEmpty ? nil : items[items.count - 1]
    }
}

// 类型约束
/*
func somFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) {
//    func body
}
*/
func findIndex<T: Equatable>(of valueToFind: T, in array:[T]) -> Int? {
    for (index, value) in array.enumerated() {
        if value == valueToFind {
            return index
        }
    }
    return nil
}

// 关联类型(协议使用泛型)
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]
    }
}

// 泛型+where
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
    }
    
    return true
}

//extension Stack wherr Element : Equatable {
//    // code
//}

extension Container where ItemType: Equatable {
    // code
}

extension Container where ItemType == Double {
    // code
}

// 泛型下标
extension Container {
    subscript<Indices: Sequence>(indics: Indices) -> [ItemType] where Indices.Iterator.Element == Int {
        var result = [ItemType]()
        for index in indics {
            result.append(self[index])
        }
        return result
    }
}

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[[0, 1]])

posted @ 2022-02-21 09:10  weicy  阅读(45)  评论(0编辑  收藏  举报