擴(kuò)展介紹
擴(kuò)展 就是為一個(gè)已有的類、結(jié)構(gòu)體鞠眉、枚舉類型或者協(xié)議類型添加新功能欣孤。這包括在沒有權(quán)限獲取原始源代碼的情況下擴(kuò)展類型的能力(即 逆向建模 )。擴(kuò)展和 Objective-C 中的分類類似呀潭。
OC與Swift對(duì)比
與 Objective-C 不同的是钉迷,Swift 的擴(kuò)展沒有名字。
擴(kuò)展的功能
- 添加計(jì)算型屬性和計(jì)算型類型屬性
- 定義實(shí)例方法和類型方法
- 提供新的構(gòu)造器
- 定義下標(biāo)
- 定義和使用新的嵌套類型
- 是一個(gè)已有類型符合某個(gè)協(xié)議
- 對(duì)協(xié)議進(jìn)行擴(kuò)展钠署,提供協(xié)議要求的實(shí)現(xiàn)糠聪,或者添加額外的功能。
擴(kuò)展的注意點(diǎn)
- 擴(kuò)展可以為一個(gè)類型添加新的功能谐鼎,但是不能重寫已有的功能
- 如果你通過擴(kuò)展為一個(gè)已有類型添加新功能舰蟆,那么新功能對(duì)該類型的所有已有實(shí)例都是可用的,即使它們是在這個(gè)擴(kuò)展定義之前創(chuàng)建的狸棍。
- 擴(kuò)展可以添加新的計(jì)算型屬性身害,但是不可以添加存儲(chǔ)型屬性,也不可以為已有屬性添加屬性觀察器草戈。
- 擴(kuò)展能為類添加新的便利構(gòu)造器塌鸯,但是它們不能為類添加新的指定構(gòu)造器或析構(gòu)器。指定構(gòu)造器和析構(gòu)器必須總是由原始的類實(shí)現(xiàn)來提供唐片。
擴(kuò)展的語法
使用關(guān)鍵字 extension 來聲明擴(kuò)展:
extension SomeType {
// 為 SomeType 添加的新功能寫到這里
}
擴(kuò)展計(jì)算型屬性
擴(kuò)展可以為已有類型添加計(jì)算型實(shí)例屬性和計(jì)算型類型屬性丙猬。
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
}
擴(kuò)展實(shí)現(xiàn)協(xié)議
通過擴(kuò)展使一個(gè)已有類型滿足一個(gè)或多個(gè)協(xié)議
extension SomeType: SomeProtocol, AnotherProctocol {
// 協(xié)議實(shí)現(xiàn)寫到這里
}
擴(kuò)展構(gòu)造器
- 擴(kuò)展能為類添加新的便利構(gòu)造器,但是它們不能為類添加新的指定構(gòu)造器或析構(gòu)器费韭。指定構(gòu)造器和析構(gòu)器必須總是由原始的類實(shí)現(xiàn)來提供茧球。
類類型擴(kuò)展構(gòu)造器規(guī)則比較簡單,這里不再講解星持,值類型擴(kuò)展構(gòu)造器比較復(fù)雜抢埋,下面詳細(xì)說明。 - 如果結(jié)構(gòu)體(值類型)或類(類類型)的所有屬性都有默認(rèn)值督暂,同時(shí)沒有自定義的構(gòu)造器羹令,那么swift會(huì)給這些結(jié)構(gòu)體或類提供一個(gè)默認(rèn)構(gòu)造器,這個(gè)默認(rèn)構(gòu)造器將簡單地創(chuàng)建一個(gè)所有屬性值都設(shè)置為默認(rèn)值的實(shí)例损痰。
- 值類型如果定義了一個(gè)自定義的構(gòu)造器福侈,那么你將無法訪問默認(rèn)構(gòu)造器,以及無法訪問逐一成員構(gòu)造器卢未。
- 如果你使用擴(kuò)展為一個(gè)值類型添加構(gòu)造器肪凛,且該值類型的原始實(shí)現(xiàn)中未定義任何定制的構(gòu)造器時(shí)堰汉,你可以在擴(kuò)展中的構(gòu)造器里調(diào)用逐一成員構(gòu)造器。如果該值類型為所有存儲(chǔ)型屬性提供了默認(rèn)值伟墙,你還可以在擴(kuò)展中的構(gòu)造器里調(diào)用默認(rèn)構(gòu)造器翘鸭。
具體例子
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()
}
提供一個(gè)額外的接受指定中心點(diǎn)和大小的構(gòu)造器來擴(kuò)展 Rect 結(jié)構(gòu)體:
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)
}
}
擴(kuò)展方法
擴(kuò)展可以為已有類型添加新的實(shí)例方法和類型方法。
extension Int {
func repetitions(task: () -> Void) {
for _ in 0..<self {
task()
}
}
}
擴(kuò)展可變實(shí)例方法
通過擴(kuò)展添加的實(shí)例方法也可以修改該實(shí)例本身戳葵。結(jié)構(gòu)體和枚舉類型中修改 self 或其屬性的方法必須將該實(shí)例方法標(biāo)注為 mutating就乓,正如來自原始實(shí)現(xiàn)的可變方法一樣。
下面的例子為 Swift 的 Int 類型添加了一個(gè)名為 square 的可變方法拱烁,用于計(jì)算原始值的平方值:
extension Int {
mutating func square() {
self = self * self
}
}
var someInt = 3
someInt.square()
// someInt 的值現(xiàn)在是 9
擴(kuò)展下標(biāo)
擴(kuò)展可以為已有類型添加新下標(biāo)生蚁。
extension Int {
subscript(var digitIndex: Int) -> Int {
var decimalBase = 1
while digitIndex > 0 {
decimalBase *= 10
--digitIndex
}
return (self / decimalBase) % 10
}
}