Swift學習這二十二:擴展(extension)
擴展(extension)擴展是向一個已有的類、結構體或枚舉類型添加新的功能。在swift中擴展是沒有名字的,
但在Objective-C中Category是有名字的,而且隻能擴展類(類別)
如在Swift中擴展是這麼寫的:
extension String {
func reverseString() -> String {
// do something if necessary
}
}
在Objective-C中,是這麼寫的:
@interface NSString (ReverseStringExtension)
- (NSString *)reverseString; // implementent in .m file
@end
Swift中擴展可以:
(1)添加計算實例屬性(computed property)和計算類屬性
(2)定義實例方法和類方法
(3)提供新的構造器
(4)定義下標(subscript)
(5)定義和使用新的嵌套類型
(6)使一個遵守某個接口
擴展語法(Extension syntax)
聲明擴展的關鍵字extension
extension SomteType {
// add sth
}
可以擴展類型時讓類型遵守協議:
extension SomteType : SomeProtocol, OtherProtocol {
// do sth if necessary
}
擴展類型,添加計算屬性:
// 添加長度單位屬性
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
println("One inch is \(oneInch) meters") // prints One inch is 0.0254 meters
let threeFeet = 3.ft
println("Three feet is \(threeFeet) meters") // prints Three feet is 0.914399970739201 meters
let sum = 10.4.km + 122.5.km // 這麼寫法是不是很方便就能進行轉換?Yes
注意:擴展可以添加新的計算屬性,但不能添加存儲屬性,也不能向已有屬性添加屬性觀察。
給值類型擴展新的構造器。
如果使用擴展給值類型添加一個構造器,如果該類型所有屬性已經有默認值,但沒有定製任何構造器,
此時我們可以調用默認的構造器和成員逐一構造器。
struct Size {
var width = 0.0
var height = 0.0
}
struct Point {
var x = 0.0
var y = 0.0
}
struct Rect {
var origin = Point()
var size = Size()
}
// 這裏因為Rect結構體都提供了屬性的默認值,它可以自動會有一個默認的構造器和一個成員逐一的構造器,
// 即:init()方法和init(origin:Point, size: Size)
// 那麼我們可以直接使用:
let defaultRect = Rect() // 調用默認構造器
let memberwiseRect = Rect(origin: Point(x: 2.0, y: 2.0), size: Size(width: 5.0, height: 5.0))
// 下麵我們給Rect擴展一個構造器
extension Rect {
init(center: Point, size: Size) {
let originX = center.x - size.width / 2.0
let originY = center.y - size.height / 2.0
// 調用本類自動得到的成員逐一構造器
self.init(origin: Point(x: originX, y: originY), size: size)
}
}
擴展方法:類方法(引用類型)、靜態方法(值類型)和實例方法、修改實例方法
extension Int {
// 參數是一個單類型的閉包,沒有參數,沒有返回值的閉包
func repetions(task: () -> ()) {
for i in 0..self {
task()
}
}
// 僅是例子,這是不好的設計
static func multiply(a: Int, b: Int) -> Int {
return a * b
}
// 要修改Self,就需要是可改類型方法,需要加上關鍵字mutating
mutating func square() {
self = self * self
}
}
let number = 4
number.repetions { // 使用了trailing closure
println("test extension")
}
// test extension
// test extension
// test extension
// test extension
println(Int.multiply(2, 3)) // prints 6
println(3.square()) // prints 9
下標(subscripts)
擴展可以向一個已有類型添加新下標。如下:
extension Int {
// 下標[n]會返回十進製數字從右向左第n個數字
subscript(index: Int) -> Int {
var decimalBase = 1
for _ in 1...index {
decimalBase *= 10
}
return (self / decimalBase) % 10
}
}
println(746381295[0])
// returns 5
println(746381295[1])
// returns 9
println(746381295[2])
// returns 2
println(746381295[8])
// returns 7
總結:個人認識擴展是很好用的功能,在項目中,會把通常的基礎輔助方法擴展到已有類中,
這樣可以方便整個工程的使用。
最後更新:2017-04-03 07:57:02