擴展:在不須要訪問源碼的狀況下,爲現有的類,結構,枚舉或協議類型添加了新功能。和Objective-C
的分類很相似,不一樣的是Swift的擴展沒有名稱。 Swift的擴展具有的能力:git
注意:擴展能夠給一個類型添加新的功能,可是不能覆蓋現有功能。github
Extension
語法聲明擴展須要使用Extension
關鍵字:編程
extension SomeType {
// 可添加擴展的功能
}
複製代碼
擴展能夠擴展示有類型以使其採用一個或多個協議。swift
extension SomeType: SomeProtocol, AnotherProtocol {
// 可添加協議要求的實現
}
複製代碼
注意:若是定義擴展爲現有類型添加新的功能,則此新功能在全部該類型已存在的實例上都是可用的,即便實例在定義擴展以前被建立。bash
擴展能夠添加實例計算屬性和類計算屬性。下例向Swift的內置Double
類型添加了五個計算實例屬性做爲距離單位:微信
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("一英寸是 \(oneInch) 米")
// Prints "一英寸是 0.0254 米"
let threeFeet = 3.ft
print("三英尺是 \(threeFeet) 米")
// Prints "三英尺是 0.914399970739201 米"
let aMarathon = 42.km + 195.m
print("馬拉松長 \(aMarathon) 米")
// Prints "馬拉松長 42195.0 米"
複製代碼
注意:擴展能夠添加新的計算屬性,可是不能添加存儲屬性,也不能爲現有屬性添加屬性觀察者。源碼分析
擴展能夠爲現有類型添加初始化方法。post
擴展也能夠爲一個Class
類型添加新的便利初始化方法,可是不能爲一個Class
類型添加新的指定初始化方法或反初始化方法。指定初始化方法或反初始化方法必須由原始的類實現。ui
若是使用擴展爲值類型添加一個初始化方法,該值類型爲其全部存儲屬性提供了默認值,而且沒有自定義的初始化方法,則咱們能夠在該值類型擴展中的初始化方法裏調用默認的初始化方法或調用按成員生成的初始化方法。若值類型原始實現時,提供了自定義的初始化方法,則在該值類型擴展中的初始化方法裏調用其自定義的初始化方法。 注:若想自定義的值類型既能調用默認初始化又能調用成員初始化還要能調用自定義的初始化,則這個自定義的初始化方法必須寫在extension
中。
若是使用擴展爲聲明在其餘模塊的結構體添加初始化方法,則新的初始化方法不能訪問self
屬性,直到該結構體從其定義的模塊中調用了初始化方法。
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()
init(origi:Point,siz:Size) {
origin = origi
size = siz
}
}
extension Rect {
init(center:Point,size:Size) {
let originX = center.x - (size.width / 2)
let originY = center.y - (size.height / 2)
self.init(origi: Point(x: originX, y: originY), siz: size)
//! `Rect`原始定義中未自定義初始化方法則此處應該使用默認初始化方法或者成員初始化方法:`self.init(origin: Point(x: originX, y: originY), size: size)`
}
}
複製代碼
擴展爲現有類型添加實例方法和類方法。
extension Int {
func repetitions(task: () -> Void) {
for _ in 0..<self {
task()
}
}
}
//調用 輸出三次`Hello!`
3.repetitions {
print("Hello!")
}
複製代碼
值類型擴展中能夠添加使用mutating
修飾的實例方法,容許修改實例自己。
extension Int {
mutating func square() {
self = self * self
}
}
var someInt = 3
someInt.square() // someInt : 9
複製代碼
擴展能夠爲現有類型添加新的下標。
//倒序輸出一個整型數
extension Int {
subscript(digitIndex:Int)->Int {
var baseNum = 1
for _ in 0..<digitIndex {
baseNum *= 10
}
assert(baseNum <= self, "整數的索引越界了")
return (self/baseNum)%10
}
}
print(123456[5]) // 1
複製代碼
擴展可爲現有類,結構體,枚舉添加新的嵌套類型。
extension Int {
enum Status : String,CaseIterable {
case NoAuth = "NoAuth"
case RequestError = "RequestError"
case None = "None"
}
var netStatus : String {
switch self {
case 401:
return Status.NoAuth.rawValue
case let x where x >= 500 :
return Status.RequestError.rawValue
default:
return Status.None.rawValue
}
}
}
print(401.netStatus) //!< NoAuth
print(500.netStatus) //!< RequestError
print(402.netStatus) //!< None
複製代碼
參考資料: swift 5.1官方編程指南
瞭解更多iOS及相關新技術,請關注咱們的公衆號:
關注咱們的途徑有:
QiShare(簡書)
QiShare(掘金)
QiShare(知乎)
QiShare(GitHub)
QiShare(CocoaChina)
QiShare(StackOverflow)
QiShare(微信公衆號)
推薦文章:
Swift 5.1 (18) - 嵌套類型 Swift 5.1 (17) - 類型轉換與模式匹配 淺談編譯過程
深刻理解HTTPS 淺談 GPU 及 「App渲染流程」
iOS 查看及導出項目運行日誌
Flutter Platform Channel 使用與源碼分析
開發沒切圖怎麼辦?矢量圖標(iconFont)上手指南
DarkMode、WKWebView、蘋果登陸是否必須適配?
奇舞團安卓團隊——aTaller
奇舞週刊