美文网首页
Swift 泛型⑫

Swift 泛型⑫

作者: Aliv丶Zz | 来源:发表于2020-08-06 15:42 被阅读0次


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

    C++ 是通过实现多个不同类型的方法来实现泛型
    Swift 是通过传入泛型的元类型来实现泛型

    1. 交换两个Int类型的值
    func swapValues(_ v1: inout Int, _ v2: inout Int)  {
        let temp = v1
        v1 = v2
        v2 = temp
    }
    
    var n1 = 10
    var n2 = 20
    swapValues(&n1, &n2)
    print(n1, n2) // 20 10
    
    1. 交换两个入参的值(可能是Int,Double,String),这个时候就要用到泛型
    func swapValues2<T>(_ v1: inout T, _ v2: inout T)  {
        (v1,v2) = (v2,v1)
    }
    
    var a = 10
    var b = 20
    swapValues2(&a, &b)
    print(a, b)//20 10
    
    a = "ABC"
    b = "abc"
    swapValues2(&a, &b)
    print(a, b)//abc ABC
    

    对于C++来说,会分别生成
    func swapValues2(_ v1: inout Int, _ v2: inout Int)
    以及 func swapValues2(_ v1: inout String, _ v2: inout String) 两个函数

    对于Swift来说,
    在传入参数时,会把该参数的元类型(type metadata)一起传入

    1. 泛型函数赋值给变量
    func test<T1, T2>(_ v1: T1, _ v2 : T2) -> [Any] {
        return [v1,v2]
    }
    var fn : (Int, Double) ->([Any]) = test
    
    print(fn(10,20.0))
    
    1. 泛型类
    class Stack<T> {
        var elements = [T]()
        func push(element: T)  {
            elements.append(element)
        }
        func pop()  {
            elements.removeLast()
        }
        func top() -> T {
           elements.last!
        }
    }
    
    var stac = Stack<Int>()
    stac.push(element: 5)
    stac.push(element: 6)
    stac.pop()
    print(stac.elements)
    print(stac.top())
    /*
    [5, 6]
    6
    */
    
    • 泛型类的继承
    class subStack<T>: Stack<T> {
        
    }
    
    1. 关联类型(协议中实现泛型)
    • 关联类型的作用:给协议中用到的类型定义一个占位名称
    • 协议中可以拥有多个关联类型
    protocol Stackable {
        associatedtype Element// 关联类型
        mutating func push(_ element: Element)
        mutating func pop() -> Element
        func top()  -> Element
        func size() -> Int
    }
    
    class StringStack: Stackable {
        typealias Element  = String//给关联类型设定真实类型 可省略
    
        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
        }
    }
    
    class IntStack<E> :Stackable{
        typealias E  =  Int //给关联类型设定真实类型 可省略
        var elements = [Int]()
            
        func push(_ element: Int) {
            elements.append(element)
        }
        func pop() -> Int {
            elements.removeLast()
        }
        func top() -> Int {
            elements.last!
        }
        func size() -> Int {
            elements.count
        }
    }
    
    1. 类型约束
    protocol Runnable{
    }
    
    func lxys(){
        
        class Person{}
        func swapValues<T: Person&Runnable>(_ a: inout T, _ b: inout T ){
            (a, b) = (b,a)
        }
    }
    

    【泛型使用注意点】
    示例1: 协议中有associatedtype

    image.png
    解决方案1:强制转换时可能会出错。
    protocol Runnable {
        associatedtype Speed
        var speed : Speed{get}
    }
    
    class Person: Runnable {
        var speed: Double {
            10.0
        }
        
    }
    
    class Car: Runnable {
        var speed: Int {
            20
        }
    }
    
    //func get(_ type: Int) -> Runnable {
    //    if type == 0 {
    //        return Person()
    //    }
    //    return Car()
    //}
    func get<T: Runnable>(_ type: Int) -> T {
        if type == 0 {
            return Person() as! T
        }
        return Car() as! T
    }
    

    解决方案2: 不透明类型 some

    • 使用some关键字声明一个不透明类型
    • some限制只能返回一种类型
    • some一般可以用在返回值类型上,也可以用在属性类型上面
    // 解决方案2
    func get(index: Int) -> some Runnable {
    
        return Car()
    }
    
    class Person{
        var per: some Runable{
            return Dog()
        }
    }
    

    相关文章

      网友评论

          本文标题:Swift 泛型⑫

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