概要
擴(kuò)展是給已經(jīng)存在的類(class)躬柬,結(jié)構(gòu)體(structure)丑罪,枚舉類型(enumeration)和協(xié)議(protocol)增加新的功能钢属。類似Objective-C中的Category哗戈,不同的是婆排,Extension沒有名字荒椭。擴(kuò)展可以做以下事情:
- 增加計(jì)算實(shí)例屬性和計(jì)算類型屬性
- 定義實(shí)例方法和類型方法
- 提供新的初始化器
- 定義下標(biāo)
- 定義和使用新的內(nèi)置類型
- 讓一個(gè)存在的類型服從一個(gè)協(xié)議
注:擴(kuò)展可以增加新的功能谐鼎,但是不能覆蓋已有的功能
擴(kuò)展的語法
使用extension關(guān)鍵字,如下所示趣惠。
extension SomeType{
//new functionality to add to SomeType goes here
}
extension SomeType: SomeProtocol, AnotherProtocol{
//implementation of protocol requirements goes here
}
注意:如果你給已經(jīng)存在的類型擴(kuò)展了新的功能狸棍,不管你在什么時(shí)候擴(kuò)展,盡管你是在實(shí)例定義之后再擴(kuò)展的味悄,那么這個(gè)類型所有的實(shí)例都可以使用這個(gè)新功能草戈,
計(jì)算屬性
擴(kuò)展可以給已經(jīng)存在的類型增加計(jì)算實(shí)例屬性和計(jì)算類型屬性,如以下擴(kuò)展了Double類型:
extension Double{
var km : Double { return self * 1000.0 }
var m: Double { return self }
var cm: Double { return self / 100.0 }
var mm: Double { return self / 1000.0 }
var ft: Double { return self / 3.28084 }
}
let oneInch = 25.4.mm;
print("One inch is \(oneInch)meters")
構(gòu)造方法(Initializers)
可以擴(kuò)展一個(gè)類型實(shí)現(xiàn)自定義構(gòu)造方法侍瑟,但是只能增加便利構(gòu)造方法(Convenience Initializers)唐片,不能增加指定構(gòu)造方法(Designated Initializers)。
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)體沒有自定義的構(gòu)造方法丢习,因?yàn)槠鋵傩远加谐跏贾登4ィ韵到y(tǒng)提供了一個(gè)默認(rèn)構(gòu)造方法和逐一成員構(gòu)造方法,在增加構(gòu)造方法時(shí)咐低,可以調(diào)用逐一成員構(gòu)造方法揽思。要確保類型中所有的存儲(chǔ)屬性都有初始值。
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)
}
}
方法
擴(kuò)展可以增加實(shí)例方法和類型方法,如下所示见擦。
extension Int{
funcrepetitions(task: () -> Void) {
for _ in 0..<self {
task()
}
}
}
4.repetitions { //尾隨閉包
print("hello")
}
可變實(shí)例方法(Mutating Instance Methods)
擴(kuò)展增加的實(shí)例方法可以修改實(shí)例本身钉汗。結(jié)構(gòu)體和枚舉類型中的方法如果想要修改實(shí)例本身或者屬性的話需要用mutating
來修飾方法,所以擴(kuò)展這樣的方法也需要加mutating
鲤屡。
extension Int{
mutating func square() {
self = self * self
print(self)
}
}
var someInt = 3
someInt.square()
下標(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
內(nèi)置類型
擴(kuò)展可以給存在的類、結(jié)構(gòu)體和枚舉類型增加新的內(nèi)置類型酒来。
extension Int{
enumKind {
casenegative, zero, positive
}
var kind: Kind {
switch self {
case 0:
return .zero
case let x where x > 0:
return .positive
default:
return .negative
}
}
}
func printIntegerKinds(_numbers: [Int]) {
for number in numbers {
switch number.kind {
case .negative:
print("-", terminator: "")
case .zero:
print("0", terminator: "")
case .positive:
print("+", terminator: "")
}
}
print("")
}
printIntegerKinds([3, 19, -27, 0, -6, 0, 7])
// Prints "+ + - 0 - 0 +