概要
擴展是給已經存在的類(class)
,結構體(structure)
,枚舉類型(enumeration)
和協議(protocol
增加新的功能。類似Objective-C中的Category
,不同的是,Extension
沒有名字。擴展可以做以下事情:
- 增加計算實例屬性和計算類型屬性
- 定義實例方法和類型方法
- 提供新的初始化器
- 定義下標
- 定義和使用新的內置類型
- 讓一個存在的類型服從一個協議
注:擴展可以增加新的功能,但是不能覆蓋已有的功能
擴展的語法
使用extension關鍵字,如下所示。
extension SomeType{
//new functionality to add to SomeType goes here
}
extension SomeType: SomeProtocol, AnotherProtocol{
//implementation of protocol requirements goes here
}
如果你給已經存在的類型擴展了新的功能,不管你在什么時候擴展,盡管你是在實例定義之后再擴展的,那么這個類型所有的實例都可以使用這個新功能
計算屬性
擴展可以給已經存在的類型增加計算實例屬性和計算類型屬性,如以下擴展了Double類型:
extension Double{
var km : Double { return self * 1000.0 }
var m: Double { return self }
var cm: Double { return self / 100.0 }
var mm: Double { return self / 1000.0 }
var ft: Double { return self / 3.28084 }
}
let oneInch = 25.4.mm;
print("One inch is \(oneInch)meters")
構造方法(Initializers)
可以擴展一個類型實現自定義構造方法,但是只能增加便利構造方法(Convenience Initializers),不能增加指定構造方法(Designated Initializers)。
struct Size {
var width = 0.0, height = 0.0
}
struct Point {
var x = 0.0, y = 0.0
}
struct Rect {
var origin = Point()
var size = Size()
}
extension Rect{
init(center: Point, size: Size) {
let originX = center.x - (size.width / 2)
let originY = center.y - (size.height / 2)
self.init(origin: Point(x: originX, y: originY), size: size)
}
}
方法
擴展可以增加實例方法和類型方法,如下所示。
extension Int{
funcrepetitions(task: () -> Void) {
for _ in 0..<self {
task()
}
}
}
4.repetitions { //尾隨閉包
print("hello")
}
可變實例方法(Mutating Instance Methods)
擴展增加的實例方法可以修改實例本身。結構體和枚舉類型中的方法如果想要修改實例本身或者屬性的話需要用mutating來修飾方法,所以擴展這樣的方法也需要加mutating。
extension Int{
mutating func square() {
self = self * self
print(self)
}
}
var someInt = 3
someInt.square()