擴(kuò)展可以向已有類型添加新的構(gòu)造器。這可以讓你擴(kuò)展其它類型,將你自己的定制類型作為構(gòu)造器參數(shù),或者提供該類型的原始實(shí)現(xiàn)中沒(méi)有包含的額外初始化選項(xiàng)。
擴(kuò)展能向類中添加新的便利構(gòu)造器,但是它們不能向類中添加新的指定構(gòu)造器或析構(gòu)函數(shù)。指定構(gòu)造器和析構(gòu)函數(shù)必須總是由原始的類實(shí)現(xiàn)來(lái)提供。
注意:
如果你使用擴(kuò)展向一個(gè)值類型添加一個(gè)構(gòu)造器,該構(gòu)造器向所有的存儲(chǔ)屬性提供默認(rèn)值,而且沒(méi)有定義任何定制構(gòu)造器(custom initializers),那么對(duì)于來(lái)自你的擴(kuò)展構(gòu)造器中的值類型,你可以調(diào)用默認(rèn)構(gòu)造器(default initializers)和逐一成員構(gòu)造器(memberwise initializers)。
正如在值類型的構(gòu)造器授權(quán)中描述的,如果你已經(jīng)把構(gòu)造器寫(xiě)成值類型原始實(shí)現(xiàn)的一部分,上述規(guī)則不再適用。
下面的例子定義了一個(gè)用于描述幾何矩形的定制結(jié)構(gòu)體Rect。這個(gè)例子同時(shí)定義了兩個(gè)輔助結(jié)構(gòu)體Size和Point,它們都把0.0作為所有屬性的默認(rèn)值:
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()
}
因?yàn)榻Y(jié)構(gòu)體Rect提供了其所有屬性的默認(rèn)值,所以正如默認(rèn)構(gòu)造器中描述的,它可以自動(dòng)接受一個(gè)默認(rèn)的構(gòu)造器和一個(gè)成員級(jí)構(gòu)造器。這些構(gòu)造器可以用于構(gòu)造新的Rect實(shí)例:
let defaultRect = Rect()
let memberwiseRect = Rect(origin: Point(x: 2.0, y: 2.0),
size: Size(width: 5.0, height: 5.0))
你可以提供一個(gè)額外的使用特殊中心點(diǎn)和大小的構(gòu)造器來(lái)擴(kuò)展Rect結(jié)構(gòu)體:
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)
}
}
這個(gè)新的構(gòu)造器首先根據(jù)提供的center和size值計(jì)算一個(gè)合適的原點(diǎn)。然后調(diào)用該結(jié)構(gòu)體自動(dòng)的成員構(gòu)造器init(origin:size:),該構(gòu)造器將新的原點(diǎn)和大小存到了合適的屬性中:
let centerRect = Rect(center: Point(x: 4.0, y: 4.0),
size: Size(width: 3.0, height: 3.0))
// centerRect的原點(diǎn)是 (2.5, 2.5),大小是 (3.0, 3.0)
注意:
如果你使用擴(kuò)展提供了一個(gè)新的構(gòu)造器,你依舊有責(zé)任保證構(gòu)造過(guò)程能夠讓所有實(shí)例完全初始化。