美文网首页
Swift3.1_扩展

Swift3.1_扩展

作者: Carson_Zhu | 来源:发表于2018-02-22 14:49 被阅读6次

    扩展

    就是为一个已有的类、结构体、枚举类型或者协议类型添加新功能,但是不能重写已有的功能。

    Swift中的扩展可以:

    • 添加计算型属性和计算型类型属性
    • 定义实例方法和类型方法
    • 提供新的构造器
    • 定义下标
    • 定义和使用新的嵌套类型
    • 使一个已有类型符合某个协议

    扩展语法

    使用关键字extension来声明扩展:

    extension SomeType {
        // 为 SomeType 添加的新功能写到这里
    }
    

    可以通过扩展来扩展一个已有类型,使其采纳一个或多个协议。在这种情况下,无论是类还是结构体,协议名字的书写方式完全一样:

    extension SomeType: SomeProtocol, AnotherProctocol {
        // 协议实现写到这里
    }
    

    计算型属性

    扩展可以为已有类型添加计算型实例属性和计算型类型属性。下面的例子为Swift的内建Double类型添加了五个计算型实例属性,从而提供与距离单位协作的基本支持:

    extension Int {
        var m: Int {
            return self
        }
        var cm: Int {
            return self * 100
        }
        var km: Int {
            return self * 1_000
        }
    }
    
    let threeKM = 3.km
    print(threeKM)  // 3000
    

    扩展可以添加新的计算型属性,但是不可以添加存储型属性,也不可以为已有属性添加属性观察器。

    构造器

    扩展可以为已有类型添加新的构造器。这可以让你扩展其它类型,将你自己的定制类型作为其构造器参数,或者提供该类型的原始实现中未提供的额外初始化选项。

    扩展能为类添加新的便利构造器,但是它们不能为类添加新的指定构造器或析构器。指定构造器和析构器必须总是由原始的类实现来提供。

    extension CGRect {
        init(center: CGPoint, size: CGSize) {
            let originX = center.x - (size.width / 2)
            let originY = center.y - (size.height / 2)
            self.init(x: originX, y: originY, width: size.width, height: size.height)
        }
    }
    
    let rect = CGRect(center: CGPoint(x: 50, y: 50), size: CGSize(width: 20, height: 20))
    print(rect)  // (40.0, 40.0, 20.0, 20.0)
    

    如果你使用扩展提供了一个新的构造器,你依旧有责任确保构造过程能够让实例完全初始化。

    方法

    扩展可以为已有类型添加新的实例方法和类型方法。

    extension Int {
        func double() -> Int {
            return self * 2
        }
    }
    
    print(5.double())  // 10
    
    可变实例方法

    通过扩展添加的实例方法也可以修改该实例本身。结构体和枚举类型中修改self或其属性的方法必须将该实例方法标注为mutating,正如来自原始实现的可变方法一样。

    // 报错 Cannot assign to value: 'self' is immutable
    extension Int {
        func square() {
            self = self * self
        }
    }
    
    // 正确方法
    extension Int {
        mutating func square() {
            self = self * self
        }
    }
    var someInt = 3
    someInt.square()  // 9
    

    下标

    扩展可以为已有类型添加新下标。

    extension String {
        subscript(_ digitIndex: Int) -> String {
            if digitIndex < self.characters.count {
                let index = self.index(self.startIndex, offsetBy: digitIndex)
                return String.init(self[index])
            }
            return ""
        }
    }
    
    let str = "abcdef"
    print(str[2])  // c
    

    嵌套类型

    扩展可以为已有的类、结构体和枚举添加新的嵌套类型:

    extension Int {
        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
            }
        }
    }
    

    该例子为Int添加了嵌套枚举。这个名为Kind的枚举表示特定整数的类型。具体来说,就是表示整数是正数、零或者负数。

    这个例子还为Int添加了一个计算型实例属性,即kind,用来根据整数返回适当的Kind枚举成员。

    现在,这个嵌套枚举可以和任意Int值一起使用了:

    func printIntegerKinds(_ numbers: [Int]) {
        for number in numbers {
            switch number.kind {
            case .Negative:
                print("- ", terminator: "")
            case .Zero:
                print("0 ", terminator: "")
            case .Positive:
                print("+ ", terminator: "")
            }
        }
        print("")
    }
    printIntegerKinds([3, 19, -27, 0, -6, 0, 7])
    // 打印 “+ + - 0 - 0 + ”
    

    相关文章

      网友评论

          本文标题:Swift3.1_扩展

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