擴展
擴展 就是為一個已有的類嫁审、結(jié)構(gòu)體婆翔、枚舉類型或者協(xié)議類型添加新功能云矫。這包括在沒有權(quán)限獲取原始源代碼的情況下擴展類型的能力(即 逆向建模 )。擴展和 Objective-C 中的分類類似分苇。(與 Objective-C 不同的是,Swift 的擴展沒有名字屁桑。)
Swift 中的擴展可以:
- 添加計算型屬性和計算靜態(tài)屬性
- 定義實例方法和類型方法
- 提供新的構(gòu)造器
- 定義下標(biāo)
- 定義和使用新的嵌套類型
- 使一個已有類型符合某個協(xié)議
在 Swift 中医寿,你甚至可以對協(xié)議進行擴展,提供協(xié)議要求的實現(xiàn)蘑斧,或者添加額外的功能靖秩,從而可以讓符合協(xié)議的類型擁有這些功能。
注意
擴展可以為一個類型添加新的功能竖瘾,但是不能重寫已有的功能沟突。
擴展語法(Extension Syntax)
使用關(guān)鍵字 extension
來聲明擴展:
extension SomeType {
// 為 SomeType 添加的新功能寫到這里
}
可以通過擴展來擴展一個已有類型,使其采納一個或多個協(xié)議捕传。在這種情況下惠拭,無論是類還是結(jié)構(gòu)體,協(xié)議名字的書寫方式完全一樣:
extension SomeType: SomeProtocol, AnotherProctocol {
// 協(xié)議實現(xiàn)寫到這里
}
注意
如果你通過擴展為一個已有類型添加新功能庸论,那么新功能對該類型的所有已有實例都是可用的职辅,即使它們是在這個擴展定義之前創(chuàng)建的。
計算型屬性(Computed Properties)
擴展可以為已有類型添加計算型實例屬性和計算型類型屬性聂示。下面的例子為 Swift 的內(nèi)建 Double
類型添加了五個計算型實例屬性域携,從而提供與距離單位協(xié)作的基本支持:
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")
// 打印 “One inch is 0.0254 meters”
let threeFeet = 3.ft
print("Three feet is \(threeFeet) meters")
// 打印 “Three feet is 0.914399970739201 meters”
注意
擴展可以添加新的計算型屬性,但是不可以添加存儲型屬性鱼喉,也不可以為已有屬性添加屬性觀察器涵亏。
方法
擴展可以為已有類型添加新的實例方法和類型方法。下面的例子為 Int
類型添加了一個名為 repetitions
的實例方法:
extension Int {
func repetitions(task: () -> Void) {
for _ in 0..<self {
task()
}
}
}
3.repetitions {
print("hello")
}
// hello
// hello
// hello
可變實例方法(Mutating Instance Methods)
通過擴展添加的實例方法也可以修改該實例本身蒲凶。結(jié)構(gòu)體和枚舉類型中修改 self
或其屬性的方法必須將該實例方法標(biāo)注為 mutating
气筋,正如來自原始實現(xiàn)的可變方法一樣。
下面的例子為 Swift 的 Int
類型添加了一個名為 square
的可變方法旋圆,用于計算原始值的平方值:
extension Int {
mutating func square() {
self = self * self
}
}
var someInt = 3
someInt.square()
// someInt 的值現(xiàn)在是 9
下標(biāo)(Subscripts)
擴展可以為已有類型添加新下標(biāo)宠默。這個例子為 Swift 內(nèi)建類型 Int
添加了一個整型下標(biāo)。該下標(biāo) [n]
返回十進制數(shù)字從右向左數(shù)的第 n
個數(shù)字:
-
123456789[0]
返回9
-
123456789[1]
返回8
……以此類推灵巧。
extension Int {
subscript(digitIndex: Int) -> Int {
var decimalBase = 1
for _ in 0..<digitIndex {
decimalBase *= 10
}
return (self / decimalBase) % 10
}
}
746381295[0]
// 返回 5
746381295[1]
// 返回 9
如果該 Int
值沒有足夠的位數(shù)搀矫,即下標(biāo)越界,那么上述下標(biāo)實現(xiàn)會返回 0
刻肄,猶如在數(shù)字左邊自動補 0
:
746381295[9]
// 返回 0瓤球,即等同于:
0746381295[9]