Swift 擴充套件
擴充套件就是向一個已有的類、結構體或列舉型別新增新功能。
擴充套件可以對一個型別新增新的功能,但是不能重寫已有的功能。
Swift 中的擴充套件可以:
- 新增計算型屬性和計算型靜態屬性
- 定義例項方法和型別方法
- 提供新的構造器
- 定義下標
- 定義和使用新的巢狀型別
- 使一個已有型別符合某個協議
語法
擴充套件宣告使用關鍵字 extension:
extension SomeType { // 加到SomeType的新功能寫到這裡 }
一個擴充套件可以擴充套件一個已有型別,使其能夠適配一個或多個協議,語法格式如下:
extension SomeType: SomeProtocol, AnotherProctocol { // 協議實現寫到這裡 }
計算型屬性
擴充套件可以向已有型別新增計算型例項屬性和計算型型別屬性。
例項
下面的例子向 Int 型別添加了 5 個計算型例項屬性並擴充套件其功能:
extension Int { var add: Int {return self + 100 } var sub: Int { return self - 10 } var mul: Int { return self * 10 } var div: Int { return self / 5 } } let addition = 3.add print("加法運算後的值:\(addition)") let subtraction = 120.sub print("減法運算後的值:\(subtraction)") let multiplication = 39.mul print("乘法運算後的值:\(multiplication)") let division = 55.div print("除法運算後的值: \(division)") let mix = 30.add + 34.sub print("混合運算結果:\(mix)")
以上程式執行輸出結果為:
加法運算後的值:103 減法運算後的值:110 乘法運算後的值:390 除法運算後的值: 11 混合運算結果:154
構造器
擴充套件可以向已有型別新增新的構造器。
這可以讓你擴充套件其它型別,將你自己的定製型別作為構造器引數,或者提供該型別的原始實現中沒有包含的額外初始化選項。
擴充套件可以向類中新增新的便利構造器 init(),但是它們不能向類中新增新的指定構造器或解構函式 deinit() 。
struct sum { var num1 = 100, num2 = 200 } struct diff { var no1 = 200, no2 = 100 } struct mult { var a = sum() var b = diff() } extension mult { init(x: sum, y: diff) { _ = x.num1 + x.num2 _ = y.no1 + y.no2 } } let a = sum(num1: 100, num2: 200) let b = diff(no1: 200, no2: 100) let getMult = mult(x: a, y: b) print("getMult sum\(getMult.a.num1, getMult.a.num2)") print("getMult diff\(getMult.b.no1, getMult.b.no2)")
以上程式執行輸出結果為:
getMult sum(100, 200) getMult diff(200, 100)
方法
擴充套件可以向已有型別新增新的例項方法和型別方法。
下面的例子向Int型別新增一個名為 topics 的新例項方法:
extension Int { func topics(summation: () -> ()) { for _ in 0..<self { summation() } } } 4.topics({ print("擴充套件模組內") }) 3.topics({ print("內型轉換模組內") })
以上程式執行輸出結果為:
擴充套件模組內 擴充套件模組內 擴充套件模組內 擴充套件模組內 內型轉換模組內 內型轉換模組內 內型轉換模組內
這個topics
方法使用了一個() -> ()
型別的單引數,表明函式沒有引數而且沒有返回值。
定義該擴充套件之後,你就可以對任意整數呼叫 topics
方法,實現的功能則是多次執行某任務:
可變例項方法
通過擴充套件新增的例項方法也可以修改該例項本身。
結構體和列舉型別中修改self或其屬性的方法必須將該例項方法標註為mutating,正如來自原始實現的修改方法一樣。
例項
下面的例子向 Swift 的 Double 型別添加了一個新的名為 square 的修改方法,來實現一個原始值的平方計算:
extension Double { mutating func square() { let pi = 3.1415 self = pi * self * self } } var Trial1 = 3.3 Trial1.square() print("圓的面積為: \(Trial1)") var Trial2 = 5.8 Trial2.square() print("圓的面積為: \(Trial2)") var Trial3 = 120.3 Trial3.square() print("圓的面積為: \(Trial3)")
以上程式執行輸出結果為:
圓的面積為: 34.210935 圓的面積為: 105.68006 圓的面積為: 45464.070735
下標
擴充套件可以向一個已有型別新增新下標。
例項
以下例子向 Swift 內建型別Int添加了一個整型下標。該下標[n]返回十進位制數字
extension Int { subscript(var multtable: Int) -> Int { var no1 = 1 while multtable > 0 { no1 *= 10 --multtable } return (self / no1) % 10 } } print(12[0]) print(7869[1]) print(786543[2])
以上程式執行輸出結果為:
2 6 5
巢狀型別
擴充套件可以向已有的類、結構體和列舉新增新的巢狀型別:
extension Int { enum calc { case add case sub case mult case div case anything } var print: calc { switch self { case 0: return .add case 1: return .sub case 2: return .mult case 3: return .div default: return .anything } } } func result(numb: [Int]) { for i in numb { switch i.print { case .add: print(" 10 ") case .sub: print(" 20 ") case .mult: print(" 30 ") case .div: print(" 40 ") default: print(" 50 ") } } } result([0, 1, 2, 3, 4, 7])
以上程式執行輸出結果為:
10 20 30 40 50 50