泛型

  1. 泛型視圖解決存儲不一樣的數據類型,或者方法的入參是不一樣的數據類型。這樣能夠優雅的減小了不少沒必要要的重複代碼。
func exchangeTwoValue<T>(a:inout T, b: inout T){
    let temp = a
    a = b
    b = temp
}

var a = 3
var b = 4
exchangeTwoValue(a: &a, b: &b)
print(String(a) + " " + String(b))


var c = "abc"
var d = "123"
exchangeTwoValue(a: &c, b: &d)
print(String(c) + " " + String(d))

//系統庫函數解決交互兩個值
swap(&c, &d)
print(String(c) + " " + String(d))
複製代碼
  1. 利用泛型實現一個自定義棧
//1. 利用泛型實現自定義棧
struct Stack<Element> {
    var items = [Element]()
    mutating func push(_ a: Element){
        items.append(a)
    }
    mutating func pop(){
        items.removeLast()
    }
}

var aStack = Stack<Any>()
aStack.push(1)
aStack.push(2.0)
aStack.push("1")
print(aStack.items)

aStack.pop()
print(aStack.items)
複製代碼
  1. 對泛型類型擴展
//2. 利用擴展返回棧頂
extension Stack {
    var topStack: Element? {
        return items.isEmpty ? nil : items.last
    }
}

print(aStack.topStack as Any)
複製代碼
  1. 類型約束
func findIndex<T: Equatable>(findValue: T, array: [T]) -> Int?{
    for (index, value) in array.enumerated(){
        if value == findValue {
            return index
        }
    }
    return nil
}

var a = [1,2,3,4,5]
print(findIndex(findValue: 3, array: a) as Any)
複製代碼
  1. 關聯類型
protocol Container {
    associatedtype Item
    mutating func append(item: Item)
    var count: Int{get}
    subscript(index: Int) -> Item { get }
}

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

var aStack = Stack<Any>()
aStack.push(1)
aStack.push(2.0)
aStack.push("1")
print(aStack.items)

print(aStack[2])
複製代碼
  1. 協議裏的關聯類型能夠添加條件
protocol Container {
    associatedtype Item: Equatable
    mutating func append(item: Item)
    var count: Int{get}
    subscript(index: Int) -> Item { get }
}
複製代碼
  1. 泛型Where語句
protocol Container {
    associatedtype Item
    mutating func append(_ item: Item)
    var count: Int {get}
    subscript(item: Int) -> Item{get}
}

struct Stack<Element>: Container {
    var items = [Element]()
    mutating func append(_ item: Element) {
        items.append(item)
    }

    var count: Int {
        return items.count
    }

    subscript(item: Int) -> Item {
        return items[item]
    }
}

extension Array: Container {}

func allItemsMatch<T: Container, U: Container> (a: T, b: U) -> Bool

    where T.Item == U.Item,  T.Item: Equatable  {
        if a.count != b.count {
            return false
        }

        for index in 0..<a.count {
            if a[index] != b[index] {
                return false
            }
        }

        return true
}

var a = Stack<String>()
a.append("a")
a.append("b")
a.append("c")
a.append("d")
a.append("e")
a.append("f")

var b = [
        "a",
        "1",
        "c",
        "d",
        "e",
        "f"
]

print(allItemsMatch(a: a, b: b))
複製代碼
  1. 擴展泛型協議使用where語句
protocol Container {
    associatedtype Item
    mutating func append(_ item: Item)
    var count: Int {get}
    subscript(item: Int) -> Item{get}
}

struct Stack<Element>: Container {
    var items = [Element]()
    mutating func append(_ item: Element) {
        items.append(item)
    }

    var count: Int {
        return items.count
    }

    subscript(item: Int) -> Item {
        return items[item]
    }
}

extension Array: Container {}

func allItemsMatch<T: Container, U: Container> (a: T, b: U) -> Bool

    where T.Item == U.Item,  T.Item: Equatable  {
        if a.count != b.count {
            return false
        }

        for index in 0..<a.count {
            if a[index] != b[index] {
                return false
            }
        }

        return true
}

extension Stack where Element: Equatable {
    //1. 擴展判斷是不是棧頂
    func isTopStack(item: Element) -> Bool {
        guard let topItem = items.last else {
            return false
        }
        
        return topItem == item
    }
    
    //2. 擴展判斷棧低
    func isBottomStack(item: Element) -> Bool {
        return count >= 1 && items[0] == item
    }
}

var aStack = Stack<String>()
aStack.append("a")
aStack.append("b")
aStack.append("c")

print(aStack.isTopStack(item: "c"))
print(aStack.isBottomStack(item: "b"))

//擴展Container協議,新增若是每一個元素都是小數類型,那麼能夠計算平均值
extension Container where Item == Double {
    func avg() -> Double {
        var sum = 0.0
        for item in 0..<count{
            sum += self[item]
        }
        return sum/Double(count)
    }
}

var b = [
        1.0,
        2.0,
        3.0,
        4.0
]

print(b.avg())
複製代碼
  1. 泛型下標
// 1. 封裝數據結構
protocol Container {
    associatedtype Item
    mutating func append(_ item: Item)
    var count: Int{get}
    subscript(index: Int) -> Item{get}
}

extension Array: Container {}

struct Stack<Element>: Container {
    var items = [Element]()
    mutating func append(_ item: Element) {
        items.append(item)
    }
    
    var count: Int {
        return items.count
    }
    
    subscript(index: Int) -> Element {
        return items[index]
    }
}

// 2. 給兩種數據結構擴展一個方法
extension Container {
    subscript<T: Sequence>(set: T) -> [Item]
        where T.Iterator.Element == Int {
            var items = [Item]()
            for item in set{
                items.append(self[item])
            }
            return items
    }
}

var aStack = Stack<String>()
aStack.append("a")
aStack.append("b")
aStack.append("c")
aStack.append("d")

print(aStack[[0,2,3]])

//打印以下
//["a", "c", "d"]
複製代碼
  1. 總結
    1. 泛型視圖解決存儲多種數據類型,和方法的入參是多種數據類型。
    2. 一個方法入參不用泛型切其實能夠用Any來解決。
    3. 利用Any來代替泛型很差,咱們應該在方法入參用泛型。
      1. 泛型能夠作到入參和返回值得統一性。可是Any作很少。
      2. 泛型能夠在調用時候指定特定的數據類型。可是Any也作不到。 泛型
相關文章
相關標籤/搜索