本文首發地址
請在閱讀本文章時,順手將文中的示例代碼在playground中敲一遍,這樣能加深理解!!!
閱讀該文章大約須要:15分鐘
讀完以後你能得到:
一、Extension是什麼
二、它能作什麼javascript
extension SomeType {
// new functionality to add to SomeType goes here
}複製代碼
Tip:擴展能夠爲一個類型添加新的功能,可是不能重寫已有的功能。
html
struct Student {
var name = ""
var age = 1
func print() {
}
}
extension Student {
//改行會報錯`invalid redeclaration print()`重複聲明print(),重寫變量也是不行的。
func print() {
}
}複製代碼
咱們想知道Extension在Swift中能作些什麼,最直接的方法就是查看Swift的官方文檔了。下面是文檔中指出Extension能作的六個方面。java
看完上面Extension能作的六個方面,咱們來逐條解釋說明一下:git
首先咱們要了解什麼是計算型屬性,計算型屬性(computed property)不直接存儲值,而是提供一個getter
和一個可選的setter
,來間接獲取和設置其餘屬性或變量的值。關於更多的計算型屬性的內容請自行查看官方文檔,在此再也不贅述。那麼咱們什麼場景能夠用到這個功能呢?舉一個最多見的例子,當你想訪問某個view的width的時候,一般狀況下你會這麼寫:程序員
view.frame.size.width複製代碼
可是這樣寫很長很不方便,做爲一個懶惰的程序員,這時候你就要想我能不能縮短訪問該屬性的代碼。不要猶豫了騷年,這時候你只須要寫一個UIView的Extension就能夠達到你的目的。github
extension UIView {
var x: CGFloat {
set {
self.frame.origin.x = newValue
}
get {
return self.frame.origin.x
}
}
var y: CGFloat {
set {
self.frame.origin.y = newValue
}
get {
return self.frame.origin.y
}
}
var width: CGFloat {
set {
self.frame.size.width = newValue
}
get {
return self.frame.size.width
}
}
var height: CGFloat {
set {
self.frame.size.height = newValue
}
get {
return self.frame.size.height
}
}
}複製代碼
這樣你就能夠經過來訪問該屬性。怎麼樣,有沒有感覺到Extension的便利之處。swift
view.width複製代碼
在你辛辛苦苦寫完一個Student類後,萬惡的產品過來告訴你需求改了,這時雖然你心中有一萬隻草泥馬在奔騰,可是爲了心中那份神聖的程序員的責任感(固然還有餬口的工資),你仍是要修改代碼。若是你想在不改變原始類的基礎上添加功能,那你能夠給Student類添加Extension來解決問題。app
Tip:這裏值得注意的一點是在Swift中,Extension能夠給類和類型添加,好比你也能夠給一個struct添加Extension,而在Objective-C中,你只能給類添加Extension。
ui
class Student {
var name = ""
var age = 1
}
extension Student {
func printCurrentStudentName() {
print(self.name)
}
}
var jack = Student()
jack.name = "jack"
jack.printCurrentStudentName()複製代碼
最多見的Rect一般由origin
和size
來構造初始化,可是若是在你寫完Rect的定義後,你恰恰想要經過center和size來肯定Rect(做爲一個程序員就要有一種做死的精神),那你就要用Extension來給Rect提供一個新的構造器。關於更多關於構造器的信息,請參考官方文檔spa
本例子來源官方文檔
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()
}
let defaultRect = Rect()
let memberwiseRect = Rect(origin: Point(x: 2.0, y: 2.0),
size: Size(width: 5.0, height: 5.0))複製代碼
經過Extension來給Rect添加一個新的構造器。
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)
}
}複製代碼
這樣你就能夠經過新的構造器來初始化Rect。
let centerRect = Rect(center: Point(x: 4.0, y: 4.0),
size: Size(width: 3.0, height: 3.0))
// centerRect's origin is (2.5, 2.5) and its size is (3.0, 3.0)複製代碼
經過Swift中的Extension,你能夠給已知類型添加下標。例以下面的例子就是給Int
類型添加一個下標,該下標表示十進制數從右向左的第n個數字。
本例子來源官方文檔
extension Int {
subscript(digitIndex: Int) -> Int {
var decimalBase = 1
for _ in 0..<digitIndex {
decimalBase *= 10
}
return (self / decimalBase) % 10
}
}
746381295[0]
// 5
746381295[1]
// 9複製代碼
Extensions能夠給已知的類、結構體、枚舉添加嵌套類型。下面的例子是給Int類型添加一個判斷正負數的Extension,該Extension嵌套一個枚舉。
本例子來源官方文檔
extension Int {
enum Kind {
case negative, 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 + "複製代碼
編寫使該類型遵照某個協議的Extension的語法以下:
extension SomeType: SomeProtocol, AnotherProtocol {
// implementation of protocol requirements goes here
}複製代碼
示例代碼:
protocol StudentProtocol {
var address: String { get }
}
struct Student {
var name = ""
var age = 1
}
extension Student: StudentProtocol {
var address: String {
return "address"
}
}
var jack = Student()
jack.address
//輸出 address複製代碼
若添加Extension的類型已經實現協議中的內容,你能夠寫一個空的Extension來遵照協議:
protocol StudentProtocol {
var address: String { get }
}
struct Student {
var address: String {
return "address"
}
var name = ""
var age = 1
}
extension Student: StudentProtocol {}
var jack = Student()
jack.address
//輸出 address複製代碼
下篇預告:Swift-Protocol
若本文有何錯誤或者不當之處,還望不吝賜教。謝謝!