美文网首页
Swift 泛型(Generics)

Swift 泛型(Generics)

作者: Arthur澪 | 来源:发表于2020-02-24 10:50 被阅读0次

    泛型代码让你能根据你所定义的要求,写出可以用于任何类型的灵活的、可复用的函数。泛型是 Swift 最强大的特性之一,很多 Swift 标准库是基于泛型代码构建的。

    泛型可以将类型参数化,提高代码复用率,减少代码量。

    泛型函数

    函数用了一个“占位类型”,它规定参数 a 和 b 必须都是同一个类型 T (这里姑且叫做 T ),或者说都是 T 所表示的类型。

    泛型函数可以用于任何类型。

    下面的例子:

    func swapValues<T>(_ a: inout T, _ b: inout T) { 
        (a, b) = (b, a)
    }
    
    var aa = 10
    var bb = 20
    swapValues(&aa, &bb)
    

    其中的T,T会自动推断为Int 。T还可以是其他任意类型如String。这样就不必再写一个函数来实现字符串交换了。直接调用swapValues这个函数即可。

    泛型类型

    Swift允许你定义自己的泛型类型。它们是可以用于任意类型的自定义类、结构体、枚举,和 Array、Dictionary方式类似。

    比如,自定义一个类型Stack,实现方便地存储数据到数组。

    struct Stack<Element> {
        // Element 为 占位类型,可随便起
        var items = [Element]()
    
        mutating func push(_ item: Element) {
            items.append(item)
        }
        mutating func pop() -> Element {
            return items.removeLast()
        }
    }
    
    // 创建时,指定了占位类型为 String
    var stackOfStrings = Stack<String>()
    stackOfStrings.push("uno")
    stackOfStrings.push("dos")
    stackOfStrings.push("tres")
    

    关联类型(Associated Type)

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

    protocol Stackable {
        associatedtype Element // 关联类型 ,这时未确定具体是什么类型
        mutating func push(_ element: Element)  
        mutating func pop() -> Element
        func top() -> Element
        func size() -> Int
    }
    
    class StringStack : Stackable {
        // 给关联类型 设为 String
        typealias Element = String    // typealias关键字,给类型起 别名
        var elements = [String]()
        func push(_ element: String) { 
            elements.append(element) 
        } 
        func pop() -> String { 
            elements.removeLast() 
        }
        func top() -> String { 
            elements.last! 
        }
        func size() -> Int { 
            elements.count 
        }
    }
    
    var ss = StringStack()
    ss.push("Jack")
    ss.push("Rose")
    

    协议中也可以声明多个关联类型

    类型约束

    指出一个类型形式参数必须继承自特定类,或者遵循一个特定的协议、组合协议。

    protocol Runnable { 
    
    }
    
    class Person { 
        // 指出,函数形参的类型必须继承自Person 遵守Runnable协议
        func swapValues<T : Person & Runnable>(_ a: inout T, _ b: inout T) {
            (a, b) = (b, a)
        }
    }
    

    可选项的本质是enum类型

    public enum Optional<Wrapped> : ExpressibleByNilLiteral { 
        case none
        case some(Wrapped)
        public init(_ some: Wrapped) 
    }
    
    var age: Int? = 10
    var age0: Optional<Int> = Optional<Int>.some(10) var age1: Optional = .some(10)
    var age2 = Optional.some(10)
    var age3 = Optional(10)
    age = nil
    age3 = .none
    

    相关文章

      网友评论

          本文标题:Swift 泛型(Generics)

          本文链接:https://www.haomeiwen.com/subject/osixqhtx.html