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() } let calc = mult() print ("mult 模块内 \(calc.a.num1, calc.a.num2)") print("mult 模块内 \(calc.b.no1, calc.b.no2)") let memcalc = mult(a: sum(num1: 300, num2: 500),b: diff(no1: 300, no2: 100)) print("mult 模块内 \(memcalc.a.num1, memcalc.a.num2)") print("mult 模块内 \(memcalc.b.no1, memcalc.b.no2)") extension mult { init(x: sum, y: diff) { _ = x.num1 + x.num2 _ = y.no1 + y.no2 } } let a = sum(num1: 100, num2: 200) print("Sum 模块内:\( a.num1, a.num2)") let b = diff(no1: 200, no2: 100) print("Diff 模块内: \(b.no1, b.no2)")
以上程式執行輸出結果為:
mult 模块内 (100, 200) mult 模块内 (200, 100) mult 模块内 (300, 500) mult 模块内 (300, 100) Sum 模块内:(100, 200) 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