440
技術社區[雲棲]
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