18-拓展

作者: bytebytebyte | 来源:发表于2020-10-28 00:08 被阅读0次
    //拓展1-3
    /*
     swift的扩展有点儿类似于OC的分类
     扩展可以分为枚举、结构体、类、协议添加功能,可以添加方法、计算属性、下标、(便捷)初始化器、嵌套类型、协议等等.
     扩展不能办到的事情:不能覆盖原有的功能、不能添加存储属性,不能向已有的属性添加属性观察器,不能添加父类、不能添加指定初始化器,不能添加反初始化器
     */
    //1.计算属性、下标、方法、嵌套类型
    var arr: Array<Int> = [10, 20, 30]
    extension Array {
        subscript(nullable idx: Int) -> Element? {
            if (startIndex..<endIndex).contains(idx) {
                return self[idx]
            }
            return nil
        }
    }
    print(arr[nullable: 10] as Any) //越界返回nil
    
    extension Int {
        func repeats(task: () -> Void) {
            for _ in 0..<self {
                task()
            }
        }
        mutating func square() -> Int { //方法
            self = self * self
            return self
        }
        enum Kind { //嵌套类型
            case negative, zero, positive
        }
        var kind: Kind {
            switch self {
            case 0:
                return .zero
            case let x where x > 0: return .positive
            default: return .negative
            }
        }
        subscript(digitIndex: Int) -> Int { //下标
            var decimalBase = 1
            for _ in 0..<digitIndex {
                decimalBase *= 10
            }
            return (self / decimalBase) % 10
        }
    }
    
    2.repeats {
        print(1) //1   //1
    }
    var age = 10
    age.square()
    print(age) //100
    
    print(10.kind) //positive
    age = 456
    print(age[2]) //2 -> 4, 1 -> 5, 0 -> 6, >=3 -> 0, <0 崩溃没写好
    
    //2.协议、初始化器
    class Person {
        var age: Int
        var name: String
        init(age: Int, name: String) {
            self.age = age
            self.name = name
        }
    }
    extension Person : Equatable { //拓展协议
        static func == (left: Person, right: Person) -> Bool {
            left.age == right.age && left.name == right.name
        }
        convenience init() { //拓展便捷初始化器,不能拓展指定初始化器
            self.init(age: 0, name: "")
        }
    }
    
    struct Point {
        var x: Int = 0
        var y: Int = 0
    }
    extension Point { //拓展自定义初始化器可以保留自动生成的初始化器
        init(_ point: Point) {
            self.init(x: point.x, y: point.y)
        }
    }
    //编译器默认生成的4个初始化器
    var p1 = Point()
    var p2 = Point(x: 10)
    var p3 = Point(y: 20)
    var p4 = Point(x: 10, y: 20)
    var p5 = Point(p4) //自定义初始化器
    
    //协议和拓展
    protocol Runnable {
        init(age: Int)
    }
    class Person0 {}
    //extension Person0 : Runnable {
    //    required init(age: Int) { //required初始化器也不能写在拓展中
    //
    //    }
    //}
    
    //如果一个类型已经实现了协议的所有要求,但是还没有声明它遵守了这个协议,可以通过拓展来让它遵守这个协议
    protocol TestProtocol {
        func test()
    }
    class TestClass {
        func test() {
            print("test")
        }
    }
    extension TestClass : TestProtocol {}
    
    //编写一个函数,判断一个整数是否为奇数
    func isOdd<T : BinaryInteger> (_ i: T) -> Bool {
        i % 2 != 0
    }
    var num: Int8 = 10
    print(isOdd(num)) //false
    
    //等价
    extension BinaryInteger {
        func isOdd() -> Bool {
            self % 2 != 0
        }
    }
    print(10.isOdd()) //false
    print((-3).isOdd()) //true
    
    //拓展可以给协议提供默认实现,也间接实现可选协议的效果
    //拓展可以给协议补充协议中从未声明过的方法
    protocol TestNumProtocol {
        func test1()
    }
    extension TestNumProtocol {
        func test1() {
            print("TestNumProtocol test1")
        }
        func test2() {
            print("TestNumProtocol test2")
        }
    }
    class TestNumClass : TestNumProtocol {}
    var cls = TestNumClass()
    cls.test1() //TestNumProtocol test1
    cls.test2() //TestNumProtocol test2
    var cls2 : TestNumProtocol = TestNumClass()
    cls2.test1() //TestNumProtocol test1
    cls2.test2() //TestNumProtocol test2
    
    class TestNumClass1 : TestNumProtocol {
        func test1() {
            print("TestNumClass1 test1")
        }
        func test2() {
            print("TestNumClass1 test2")
        }
    }
    var cls3 = TestNumClass1()
    cls3.test1() //TestNumClass1 test1
    cls3.test2() //TestNumClass1 test2
    var cls4 : TestNumProtocol = TestNumClass1()
    cls4.test1() //TestNumClass1 test1 //去协议找
    cls4.test2() //TestNumProtocol test2 //协议直接没有去拓展找
    
    //3.泛型
    class Stack<E> {
        var elements = [E]()
        func push(_ element: E) {
            elements.append(element)
        }
        func pop() -> E {
            elements.removeLast()
        }
        func size() -> Int {
            elements.count
        }
    }
    extension Stack {
        func top() -> E { //拓展中依然可以使用原类型中的泛型类型
            elements.last!
        }
    }
    extension Stack : Equatable where E : Equatable { //符合条件才拓展
        static func == (left: Stack, right: Stack) -> Bool {
            left.elements == right.elements
        }
    }
    

    相关文章

      网友评论

          本文标题:18-拓展

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