15-泛型

作者: bytebytebyte | 来源:发表于2020-10-27 22:54 被阅读0次
    //泛型1-9
    //1.泛型:泛型可以将类型参数化,提高代码复用率,减少代码量
    func swapValues<T>(_ a: inout T, _ b: inout T) {
        (a, b) = (b, a)
    }
    var i1 = 10
    var i2 = 20
    swapValues(&i1, &i2)
    var d1 = 10.0
    var d2 = 20.0
    swapValues(&d1, &d2)
    struct Date {
        var year = 0, month = 0, day = 0
    }
    var dd1 = Date(year: 2020, month: 9, day: 22)
    var dd2 = Date(year: 2020, month: 9, day: 23)
    swapValues(&dd1, &dd2)
    //泛型函数赋值给变量
    func test<T1, T2>(_ t1: T1, _ t2: T2){}
    var fn: (Int, Double) -> () = test
    
    class Stack<E> {
        var elements = [E]()
        func push(_ element: E) { elements.append(element) }
        func pop() -> E { elements.removeLast() }
        func top() -> E { elements.last! }
        func size() -> Int { elements.count }
    }
    class SubStack<E> : Stack<E> {}
    var stack = Stack<Int>()
    stack.push(11)
    stack.push(22)
    stack.push(33)
    print(stack.top())//33
    print(stack.pop())//33
    print(stack.pop())//22
    print(stack.pop())//11
    print(stack.size())//0
    
    struct Stack0<E> {
        var elements = [E]()
        mutating func push(_ element: E){ elements.append(element) }
        mutating func pop() -> E { elements.removeLast() }
        func top() -> E { elements.last! }
        func size() -> Int { elements.count }
    }
    enum Score<T> {
        case point(T)
        case grade(String)
    }
    let score0 = Score<Int>.point(100)
    let score1 = Score.point(99)
    let score2 = Score.point(99.5)
    let score3 = Score<Int>.grade("A")
    
    //2.关联泛型
    //关联泛型的作用:给协议中用到的类型定义一个占位名称,协议中可以拥有多个关联类型
    protocol Stackable {
        associatedtype Element //关联泛型
        mutating func push(_ element: Element)
        mutating func pop() -> Element
        func top() -> Element
        func size() -> Int
    }
    class Stack1<E>: Stackable {
    //    typealias element = E
        var elements = [E]()
        func push(_ element: E) {
            elements.append(element)
        }
        func pop() -> E { elements.removeLast() }
        func top() -> E { elements.last! }
        func size() -> Int { elements.count }
    }
    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 }
    }
    var ss = StringStack()
    ss.push("Jack")
    ss.push("Rose")
    print(ss.top()) //Rose
    
    //4.类型约束
    protocol Runnable {}
    class Person {}
    func swapValues<T: Person & Runnable>(_ a: inout T, _ b: inout T) {
        (a, b) = (b, a)
    }
    protocol Stackable2 {
        associatedtype Element: Equatable
    }
    class Stack2<E: Equatable> : Stackable2 { typealias Element = E } 
    func equal<S1: Stackable2, S2: Stackable2>(_ s1: S1, _ s2: S2) -> Bool where S1.Element == S2.Element, S1.Element : Hashable {
        return false
    }
    var s1 = Stack2<Int>()
    var s2 = Stack2<Int>()
    var s3 = Stack2<String>()
    equal(s1, s2)
    //equal(s2, s3)
    
    //5.协议类型的注意点
    protocol Run {}
    class Per : Run {}
    class Car : Run {}
    func get(_ type: Int) -> Run {
        if type == 0 {
            return Per()
        }
        return Car()
    }
    var r1 = get(0)
    var r2 = get(1)
    
    //6.如果协议中有associatedtype
    protocol Walk {
        associatedtype Speed
        var speed: Speed { get }
    }
    class Pers : Walk {
        var speed: Double { 0.0 }
    }
    class Bus : Walk {
        var speed: Int { 0 }
    }
    
    //7.协议作为返回值类型:泛型解决
    func get<T: Run>(_ type: Int) -> T {
        if type == 0 {
            return Per() as! T
        }
        return Car() as! T
    }
    var c1: Per = get(0)
    var c2: Car = get(1)
    
    //8.协议作为返回值类型:不透明类型:使用some关键字声明一个不透明类型
    func gets(_ type: Int) -> some Run { Car() }
    var e1 = gets(0)
    var e2 = gets(1)
    //some限制只能返回一种类型
    //func get(_ type: Int) -> some Run {
    //    if type == 0 {
    //        return Per()
    //    }
    //    return Car()
    //}
    //Function declares an opaque return type, but the return statements in its body do not have matching underlying types
    //some 限制除了用在返回值类型上,一般还可以用在属性类型上
    protocol Running { associatedtype Speed }
    class Dog : Running { typealias Speed = Double }
    class Perso {
        var pet: some Running {
            return Dog()
        }
    }
    //9.可选项的本质
    //可选项的本质是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
    
    var age4: Int? = nil
    var age5 = Optional<Int>.none
    var age6: Optional<Int> = .none
    
    var ages: Int? = .none
    ages = 10
    ages = .some(20)
    ages = nil
    
    //3个等价
    switch ages {
    case let v?:
        print("some",v)
    case nil:
        print("none")
    }
    
    switch ages {
    case let .some(v):
        print("some", v)
    case .none:
        print("none")
    }
    
    if let v = ages {
        print("1", v)
    } else {
        print("2")
    }
    
    var line_:Int? = 10
    var line: Int?? = line_
    line_ = nil
    
    var line0 = Optional.some(Optional.some(10))
    line0 = .none
    var line1: Optional<Optional> = .some(.some(10))
    line1 = .none
    
    var line2: Int?? = 10
    var line3: Optional<Optional> = 10
    

    相关文章

      网友评论

          本文标题:15-泛型

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