首页 > 技术文章 > 泛型

MrTao 2016-02-04 19:24 原文

泛型代码可以让你编写适用自定义需求以及任意类型的灵活可重用的函数和类型。它的可以让你避免重复的代码,用一种清晰和抽象的方式来表达代码的意图。

泛型是 面向对象 的强大特性之一,Swift 也一样. 事实上,泛型的使用贯穿了整本语言手册,只是你可能没有发现而已。例如,Swift 的 Array 和 Dictionary 都是泛型集合。你可以创建一个 Int 数组,也可创建一个 String 数组,甚至可以是任意其他 Swift 类型的数组。同样的,你也可以创建存储任意指定类型的字典。

泛型方法

不管传进来的是什么参数, 定义一个方法交换2个值

func generics<T>(inout t:T, inout u: T) {
        let a = t;
        t = u;
        u = a;
    }

T是函数定义的一个占位类型名,因此 不会去查找名为 T 的实际类型

 

自定义泛型类

 

类型约束语法

 // 解释: T必须是NSObject/继承NSObject的子类
 //      U必须是ProtocolsGrammar/继承ProtocolsGrammar的子协议
func genericString<T: NSObject, U: ProtocolsGrammar>(t: T, u: U) {
        
}
// 解释: T 类型必须是遵守了 Equatable协议的类型才能做 == 比较, 最开始如果你只写一个T的话, 你会发现在编译的时候无法通过, 就是因为T是不明确的类型, 有些类型是==比较不了的. 所以编译器就提示错误, 我们在T 后面限定一个Equatable类型条件, 这样只有遵守这个协议的类型才可以比较, 
// 这个方法是模仿系统中的 array.indexOf()方法
func findStringIndex<T: Equatable>(array: [T], _ valueToFind: T) -> Int {
      for (index, value) in array.enumerate() {
          
          if value == valueToFind {
              return index
          }
      }
      return -1
}

关联类型

protocol ElementProtocol {
    // 声明一个类型
    typealias type
    mutating func append(t:type)
    func count() -> Int
    subscript(i: Int) -> type { get }
}

struct ArrayList<Element: NSObject>: ElementProtocol {
    var items = [Element]()
    mutating func append(t:Element) {
        items.append(t)
    }
    
    func count() -> Int {
       return items.count
    }
    subscript(i: Int) -> Element {
        get {
            return items[i]
        }
        set {
            if i != items.count {
                return
            }
            
            items.append(newValue)
        }
    }
}

 

    // 解释: c1必须是遵守 ElementProtocol协议的类型
    // where c1.type 与c2.type 必须相同
    func allItemsMatch<c1: ElementProtocol, c2: ElementProtocol where
        c1.type == c2.type
        > () -> Bool {
        return true
    }

 

推荐阅读