標籤:
拓展(Extension)
擴充就是向一個已有的類、結構體、枚舉類型或者協議類型添加新功能。這包括在沒有許可權擷取原始原始碼的情況下擴充類型的能力(即逆向建模)。擴充和 Objective-C 中的分類(categories)類似。(不過與 Objective-C 不同的是,Swift 的擴充沒有名字。)
Swift的拓展可以:
- 添加計算型屬性和計算型靜態屬性
- 定義執行個體方法和類型方法
- 提供新的構造器
- 定義下標
- 定義和使用新的巢狀型別
- 使一個已有類型符合某個協議
注意:擴充可以對一個類型添加新的功能,但是不能重寫已有的功能。
基本文法:
class SomeClass {}extension SomeClass { // 在這裡可以添加SomeClass的新功能}
一個擴充可以擴充一個已有類型,使其能夠適配一個或多個協議。當這種情況發生時,協議的名字應該完全按照類或結構體的名字的方式進行書寫:
protocol SomeProtocol { }class SomeClass {}extension SomeClass : SomeProtocol { }
計算型屬性
擴充可以向已有類型添加計算型執行個體屬性和計算型類型屬性。
注意:擴充可以添加新的計算屬性,但是不可以添加儲存屬性,也不可以向已有屬性添加屬性觀測器。
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.mmprint(oneInch)// 0.0254let threeFeet = 3.0.ftprint(threeFeet)// 0.914399970739201let aMarathon = 42.0.km + 195.0.mprint(aMarathon)// 42195
構造器
擴充可以向已有類型添加新的構造器。這可以讓你擴充其它類型,將你自己的定製類型作為構造器參數,或者提供該類型的原始實現中沒有包含的額外初始化選項。
擴充能向類中添加新的便利構造器,但是它們不能向類中添加新的指定構造器或析構器。指定構造器和析構器必須總是由原始的類實現來提供。
注意:如果你使用擴充向一個實值型別添加一個構造器,在該實值型別已經向所有的儲存屬性提供預設值,而且沒有定義任何定製構造器時,你可以在實值型別的擴充構造器中調用預設構造器和逐一成員構造器。正如在實值型別的構造器代理中描述的,如果你已經把構造器寫成實值型別原始實現的一部分,上述規則不再適用。
struct Size { var width = 0.0, height = 0.0}struct Point { var x = 0.0, y = 0.0}struct Rect { // Rect結構體為所有屬性提供了預設值,而且也沒有自訂構造器,這樣可以在拓展中調用Rect的逐一構造器和預設構造器 var origin = Point(), size = Size()}extension Rect { // 在拓展中自訂了構造器 init(center: Point, size: Size) { let x = center.x - size.width / 2 let y = center.y - size.height / 2 self.init(origin: Point(x: x, y: y), size: size) }}let rect = Rect(center: Point(x: 50, y: 50), size: Size(width: 25, height: 30))
方法
擴充可以向已有類型添加新的執行個體方法和類型方法。
extension Int { func repetitions(task: () -> ()) { for _ in 0 ..< self { task() } }}3.repetitions { print("hello") // 列印3次 "hello"}
修改執行個體方法
通過擴充添加的執行個體方法也可以修改該執行個體本身。結構體和枚舉類型中修改self
或其屬性的方法必須將該執行個體方法標註為mutating
,正如來自原始實現的修改方法一樣。
extension Int { // 定義了實值型別修改執行個體的方法 mutating func square() { self = self * self }}var number = 3number.square() // number 現在的值是 9
下標
擴充可以向一個已有類型添加新下標。
extension Int { subscript (var index: Int) -> Int { var decimalBase = 1 while index > 0 { decimalBase *= 10 index -= 1 } return self / decimalBase % 10 }}15699632[2] // return 615699632[3] // return 915699632[4] // return 915699632[5] // return 615699632[6] // return 5
巢狀型別
擴充可以向已有的類、結構體和枚舉添加新的巢狀型別:
extension Int { enum Kind { case Negative, Zero, Positive } var kind: Kind { switch self { case 0: return .Zero case let number where number > 0 : return .Positive default: return .Negative } }}func printIntegerKinds(numbers: [Int]) { for number in numbers { switch number.kind { case .Negative: print(" - ") case .Zero: print(" 0 ") default: print(" + ") } }}printIntegerKinds([0, 11, -4, 5, 0])
學習Swift -- 拓展