扩展就是向一个已有的类、结构体或枚举类型添加新功能,包含属性和方法,如果你定义了一个扩展向一个已有类型添加新功能,那么这个新功能对该类型的所有已有实例中都是可用的,即使它们是在你的这个扩展的前面定义的。
扩展语法
使用关键extension来声明一个扩展,在extension后面加类型名称
extension SomeType {
}
一个扩展可以扩展一个已有类型,使其能够适配一个或多个协议(protocol)。当这种情况发生时,接口的名字应该完全按照类或结构体的名字的方式进行书写:
extension SomeType: SomeProtocol, AnotherProctocol {
}
计算属性的扩展
extension Double { var km: Double { return self * 1_000.0 } var m: Double { return self } var cm: Double { return self / 100.0 } var mm: Double { return self / 1_000.0 } var ft: Double { return self / 3.28084 } } let oneInch = 25.4.mm print("One inch is \(oneInch) meters") // Prints "One inch is 0.0254 meters" let threeFeet = 3.ft print("Three feet is \(threeFeet) meters") // Prints "Three feet is 0.914399970739201 meters
注意:扩展可以添加新的计算属性,但是不可以添加存储属性,也不可以向已有属性添加属性观测器(property observers)。
构造方法
扩展可以向已有类型添加新的构造器。这可以让你扩展其它类型,将你自己的定制类型作为构造器参数,或者提供该类型的原始实现中没有包含的额外初始化选项。
注意:如果你使用扩展向一个值类型添加一个构造器,该构造器向所有的存储属性提供默认值,而且没有定义任何定制构造器(custom initializers),那么对于来自你的扩展构造器中的值类型,你可以调用默认构造器(default initializers)和成员级构造器(memberwise initializers)。 正如在值类型的构造器授权中描述的,如果你已经把构造器写成值类型原始实现的一部分,上述规则不再适用。
方法的扩展
extension Int { func repetitions(task: () -> ()) { for i in 0..self { task() } } }
这个repetitions方法使用了一个() -> ()类型的单参数(single argument),表明函数没有参数而且没有返回值。
定义该扩展之后,你就可以对任意整数调用repetitions方法,实现的功能则是多次执行某任务:
3.repetitions{ println("Goodbye!") } // Goodbye! // Goodbye! // Goodbye!