Swift - 泛型

  • 简述

    Swift 4 语言提供“泛型”功能来编写灵活且可重用的函数和类型。泛型用于避免重复并提供抽象。Swift 4 标准库是用泛型代码构建的。Swift 4的 'Arrays' 和 'Dictionary' 类型属于泛型集合。在数组和字典的帮助下,数组被定义为保存“Int”值和“String”值或任何其他类型。
    
    func exchange(a: inout Int, b: inout Int) {
       let temp = a
       a = b
       b = temp
    }
    var numb1 = 100
    var numb2 = 200
    print("Before Swapping values are: \(numb1) and \(numb2)")
    exchange(a: &numb1, b: &numb2)
    print("After Swapping values are: \(numb1) and \(numb2)")
    
    当我们使用playground运行上述程序时,我们得到以下结果 -
    
    Before Swapping values are: 100 and 200
    After Swapping values are: 200 and 100
    
  • 泛型函数:类型参数

    通用函数可用于访问任何数据类型,如“Int”或“String”。
    
    func exchange<T>(a: inout T, b: inout T) {
       let temp = a
       a = b
       b = temp
    }
    var numb1 = 100
    var numb2 = 200
    print("Before Swapping Int values are: \(numb1) and \(numb2)")
    exchange(a: &numb1, b: &numb2)
    print("After Swapping Int values are: \(numb1) and \(numb2)")
    var str1 = "Generics"
    var str2 = "Functions"
    print("Before Swapping String values are: \(str1) and \(str2)")
    exchange(a: &str1, b: &str2)
    print("After Swapping String values are: \(str1) and \(str2)")
    
    当我们使用playground运行上述程序时,我们得到以下结果 -
    
    Before Swapping Int values are: 100 and 200
    After Swapping Int values are: 200 and 100
    Before Swapping String values are: Generics and Functions
    After Swapping String values are: Functions and Generics
    
    函数 exchange() 用于交换上面程序中描述的值,<T> 用作类型参数。第一次调用函数 exchange() 以返回“Int”值,第二次调用函数 exchange() 将返回“String”值。多个参数类型可以包含在以逗号分隔的尖括号内。
    类型参数被命名为用户定义以了解它所持有的类型参数的用途。Swift 4 提供 <T> 作为泛型类型参数名称。但是,数组和字典等类型参数也可以命名为键、值,以标识它们属于“字典”类型。
    
    struct TOS<T> {
       var items = [T]()
       mutating func push(item: T) {
          items.append(item)
       }
       mutating func pop() -> T {
          return items.removeLast()
       }
    }
    var tos = TOS<String>()
    tos.push(item: "Swift 4")
    print(tos.items)
    tos.push(item: "Generics")
    print(tos.items)
    tos.push(item: "Type Parameters")
    print(tos.items)
    tos.push(item: "Naming Type Parameters")
    print(tos.items)
    let deletetos = tos.pop()
    
    当我们使用playground运行上述程序时,我们得到以下结果 -
    
    [Swift 4]
    [Swift 4, Generics]
    [Swift 4, Generics, Type Parameters]
    [Swift 4, Generics, Type Parameters, Naming Type Parameters]
    
  • 扩展泛型类型

    扩展堆栈属性以了解项目的顶部包含在 'extension' 关键字中。
    
    struct TOS<T> {
       var items = [T]()
       mutating func push(item: T) {
          items.append(item)
       }
       mutating func pop() -> T {
          return items.removeLast()
       }
    }
    var tos = TOS<String>()
    tos.push(item: "Swift 4")
    print(tos.items)
    tos.push(item: "Generics")
    print(tos.items)
    tos.push(item: "Type Parameters")
    print(tos.items)
    tos.push(item: "Naming Type Parameters")
    print(tos.items)
    extension TOS {
       var first: T? {
          return items.isEmpty ? nil : items[items.count - 1]
       }
    }
    if let first = tos.first {
       print("The top item on the stack is \(first).")
    }
    
    当我们使用playground运行上述程序时,我们得到以下结果 -
    
    ["Swift 4"]
    ["Swift 4", "Generics"]
    ["Swift 4", "Generics", "Type Parameters"]
    ["Swift 4", "Generics", "Type Parameters", "Naming Type Parameters"]
    The top item on the stack is Naming Type Parameters.
    
  • 类型约束

    Swift 4 语言允许“类型约束”指定类型参数是否从特定类继承,或确保协议符合标准。
    
    func exchange<T>(a: inout T, b: inout T) {
       let temp = a
       a = b
       b = temp
    }
    var numb1 = 100
    var numb2 = 200
    print("Before Swapping Int values are: \(numb1) and \(numb2)")
    exchange(a: &numb1, b: &numb2)
    print("After Swapping Int values are: \(numb1) and \(numb2)")
    var str1 = "Generics"
    var str2 = "Functions"
    print("Before Swapping String values are: \(str1) and \(str2)")
    exchange(a: &str1, b: &str2)
    print("After Swapping String values are: \(str1) and \(str2)")
    
    当我们使用playground运行上述程序时,我们得到以下结果 -
    
    Before Swapping Int values are: 100 and 200
    After Swapping Int values are: 200 and 100
    Before Swapping String values are: Generics and Functions
    After Swapping String values are: Functions and Generics
    
  • 关联类型

    Swift 4 允许通过关键字“关联类型”在协议定义内声明关联类型。
    
    protocol Container {
       associatedtype ItemType
       mutating func append(item: ItemType)
       var count: Int { get }
       subscript(i: Int) -> ItemType { get }
    }
    struct TOS<T>: Container {
       // original Stack<T> implementation
       var items = [T]()
       mutating func push(item: T) {
          items.append(item)
       }
       mutating func pop() -> T {
          return items.removeLast()
       }
       
       // conformance to the Container protocol
       mutating func append(item: T) {
          self.push(item: item)
       }
       var count: Int {
          return items.count
       }
       subscript(i: Int) -> T {
          return items[i]
       }
    }
    var tos = TOS<String>()
    tos.push(item: "Swift 4")
    print(tos.items)
    tos.push(item: "Generics")
    print(tos.items)
    tos.push(item: "Type Parameters")
    print(tos.items)
    tos.push(item: "Naming Type Parameters")
    print(tos.items)
    
    当我们使用playground运行上述程序时,我们得到以下结果 -
    
    [Swift 4]
    [Swift 4, Generics]
    [Swift 4, Generics, Type Parameters]
    [Swift 4, Generics, Type Parameters, Naming Type Parameters]
    
  • Where 条款

    类型约束使用户能够定义对与泛型函数或类型相关联的类型参数的要求。为了定义关联类型的要求,'where' 子句被声明为类型参数列表的一部分。'where' 关键字紧跟在类型参数列表之后,后跟关联类型的约束、类型和关联类型之间的相等关系。
    
    protocol Container {
       associatedtype ItemType
       mutating func append(item: ItemType)
       var count: Int { get }
       subscript(i: Int) -> ItemType { get }
    }
    struct Stack<T>: Container {
       // original Stack<T> implementation
       var items = [T]()
       mutating func push(item: T) {
          items.append(item)
       }
       mutating func pop() -> T {
          return items.removeLast()
       }
       // conformance to the Container protocol
       mutating func append(item: T) {
          self.push(item: item)
       }
       var count: Int {
          return items.count
       }
       subscript(i: Int) -> T {
          return items[i]
       }
    }
    func allItemsMatch<
    C1: Container, C2: Container
    where C1.ItemType == C2.ItemType, C1.ItemType: Equatable>
    (someContainer: C1, anotherContainer: C2) -> Bool {
       // check that both containers contain the same number of items
       if someContainer.count != anotherContainer.count {
          return false
       }
       
       // check each pair of items to see if they are equivalent
       for i in 0..<someContainer.count {
          if someContainer[i] != anotherContainer[i] {
             return false
          }
       }
       // all items match, so return true
       return true
    }  
    var tos = Stack<String>()
    tos.push(item: "Swift 4")
    print(tos.items)
    tos.push(item: "Generics")
    print(tos.items)
    tos.push(item: "Where Clause")
    print(tos.items)
    var eos = ["Swift 4", "Generics", "Where Clause"]
    print(eos)
    
    当我们使用playground运行上述程序时,我们得到以下结果 -
    
    [Swift 4]
    [Swift 4, Generics]
    [Swift 4, Generics, Where Clause]
    [Swift 4, Generics, Where Clause]