閱讀440 返回首頁    go 技術社區[雲棲]


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

  上一篇:go android ListView隱藏FooterView(headerView)
  下一篇:go jQuery Mobile頁麵跳轉切換的幾種方式