擴(kuò)展: 就是給一個(gè)現(xiàn)存類, 結(jié)構(gòu)體, 枚舉或者協(xié)議添加新的屬性和方法的語(yǔ)法, 無(wú)需目標(biāo)源碼, 就可以把想要的代碼加到目標(biāo)上面蒸矛。
但有一些限制條件需要說(shuō)明:
1.不能添加一個(gè)已經(jīng)存在的方法或者屬性;
2.添加的屬性不能是存儲(chǔ)屬性, 只能是計(jì)算屬性;
格式:
extension 某個(gè)先有類型{
//增加新的功能
}
擴(kuò)展計(jì)算屬性
class Transport {
var scope:String
init(scope:String) {
self.scope = scope
}
}
extension Transport {
var extProperty:String{
get{
return scope
}
}
}
var myTrans = Transport(scope: "飛機(jī)")
print(myTrans.extProperty)
注意
: 擴(kuò)展可以添加新的計(jì)算屬性,但它們不能添加存儲(chǔ)屬性净宵,或向現(xiàn)有屬性添加屬性觀察者赚哗。
擴(kuò)展構(gòu)造器
- 擴(kuò)展可以向類添加新的便利構(gòu)造器,但是它們不能向類添加新的指定構(gòu)造器或析構(gòu)器。指定構(gòu)造器或析構(gòu)器必須始終由原始類實(shí)現(xiàn)提供晌姚。
- 如果使用擴(kuò)展將構(gòu)造器添加到值類型中,該值類型為其所有存儲(chǔ)屬性提供默認(rèn)值歇竟,并且沒(méi)有任何自定義構(gòu)造器挥唠,則可以在擴(kuò)展的構(gòu)造器中調(diào)用該值類型的默認(rèn)構(gòu)造器和全能構(gòu)造器。
- 如果使用擴(kuò)展將構(gòu)造器添加到聲明在另一個(gè)模塊中的結(jié)構(gòu)體中焕议,則
新的構(gòu)造器只有從定義的模塊中調(diào)用了構(gòu)造器才能訪問(wèn)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()
}
Rect結(jié)構(gòu)為其所有屬性提供默認(rèn)值宝磨,所以它會(huì)自動(dòng)接收默認(rèn)構(gòu)造器和全能構(gòu)造器。這些構(gòu)造器可用于創(chuàng)建新的Rect實(shí)例:
let defaultRect = Rect()
let memberwiseRect = Rect(origin: Point(x: 2.0, y: 2.0), size: Size(width: 5.0, height: 5.0))
可以擴(kuò)展Rect結(jié)構(gòu)體以提供額外的構(gòu)造器盅安,該構(gòu)造器具有特定的中心點(diǎn)和大小:
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)
}
}
let centerRect = Rect(center: Point(x: 4.0, y: 4.0), size: Size(width: 3.0, height: 3.0))
// centerRect's origin is (2.5, 2.5) and its size is (3.0, 3.0)
注意
:如果使用擴(kuò)展來(lái)提供一個(gè)新初始化器唤锉,要確保構(gòu)造器完成之后,每個(gè)實(shí)例都被完全初始化别瞭。
擴(kuò)展方法
- 通過(guò)擴(kuò)展增加的實(shí)例方法可以修改實(shí)例本身
如果結(jié)構(gòu)體和枚舉的方法要修改self或其屬性窿祥,則需要使用mutating關(guān)鍵字標(biāo)明
extension Int {
mutating func square() {
self = self * self
}
}
var someInt = 3
someInt.square()
擴(kuò)展下標(biāo)
- 擴(kuò)展可以向已存在的類型添加下標(biāo)
extension Int {
subscript(digitIndex: Int) -> Int {
var decimalBase = 1
for _ in 0..<digitIndex {
decimalBase *= 10
}
return (self / decimalBase) % 10
}
}
746381295[0]
// returns 5
746381295[1]
// returns 9
746381295[2]
// returns 2
746381295[8]
// returns 7