在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ iOS/ 擴(kuò)展
特性(Attributes)
Access Control 權(quán)限控制的黑與白
基本運(yùn)算符(Basic Operators)
基礎(chǔ)部分(The Basics)
閉包(Closures)
擴(kuò)展
泛型參數(shù)(Generic Parameters and Arguments)
訪問(wèn)控制和 protected
語(yǔ)句(Statements)
模式(Patterns)
WWDC 里面的那個(gè)“大炮打氣球”
關(guān)于語(yǔ)言參考(About the Language Reference)
語(yǔ)法總結(jié)(Summary of the Grammar)
嵌套類(lèi)型
類(lèi)型(Types)
Swift 初見(jiàn)(A Swift Tour)
泛型
枚舉(Enumerations)
高級(jí)運(yùn)算符
繼承
析構(gòu)過(guò)程
關(guān)于 Swift(About Swift)
訪問(wèn)控制
類(lèi)和結(jié)構(gòu)體
內(nèi)存安全
Swift 與 C 語(yǔ)言指針友好合作
協(xié)議
屬性(Properties)
可選類(lèi)型完美解決占位問(wèn)題
錯(cuò)誤處理
字符串和字符(Strings and Characters)
聲明(Declarations)
自動(dòng)引用計(jì)數(shù)
Swift 里的值類(lèi)型與引用類(lèi)型
表達(dá)式(Expressions)
Swift 文檔修訂歷史
造個(gè)類(lèi)型不是夢(mèng)-白話(huà) Swift 類(lèi)型創(chuàng)建
歡迎使用 Swift
詞法結(jié)構(gòu)(Lexical Structure)
集合類(lèi)型(Collection Types)
下標(biāo)
方法(Methods)
可選鏈?zhǔn)秸{(diào)用
版本兼容性
類(lèi)型轉(zhuǎn)換
構(gòu)造過(guò)程
The Swift Programming Language 中文版
函數(shù)(Functions)
Swift 教程
控制流(Control Flow)

擴(kuò)展


1.0 翻譯:lyuka 校對(duì):Hawstein

2.0 翻譯+校對(duì):shanks

2.1 校對(duì):shanks

2.2 翻譯+校對(duì):SketchK 2016-05-16 3.0.1,shanks,2016-11-13

4.0 校對(duì):kemchenj 2017-09-21

4.1 翻譯+校對(duì):mylittleswift

本頁(yè)包含內(nèi)容:

擴(kuò)展 就是為一個(gè)已有的類(lèi)、結(jié)構(gòu)體、枚舉類(lèi)型或者協(xié)議類(lèi)型添加新功能。這包括在沒(méi)有權(quán)限獲取原始源代碼的情況下擴(kuò)展類(lèi)型的能力(即 逆向建模 )。擴(kuò)展和 Objective-C 中的分類(lèi)類(lèi)似。(與 Objective-C 不同的是,Swift 的擴(kuò)展沒(méi)有名字。)

Swift 中的擴(kuò)展可以:

  • 添加計(jì)算型屬性和計(jì)算型類(lèi)型屬性
  • 定義實(shí)例方法和類(lèi)型方法
  • 提供新的構(gòu)造器
  • 定義下標(biāo)
  • 定義和使用新的嵌套類(lèi)型
  • 使一個(gè)已有類(lèi)型符合某個(gè)協(xié)議

在 Swift 中,你甚至可以對(duì)協(xié)議進(jìn)行擴(kuò)展,提供協(xié)議要求的實(shí)現(xiàn),或者添加額外的功能,從而可以讓符合協(xié)議的類(lèi)型擁有這些功能。你可以從協(xié)議擴(kuò)展獲取更多的細(xì)節(jié)。

注意

擴(kuò)展可以為一個(gè)類(lèi)型添加新的功能,但是不能重寫(xiě)已有的功能。

擴(kuò)展語(yǔ)法

使用關(guān)鍵字 extension 來(lái)聲明擴(kuò)展:

extension SomeType {
    // 為 SomeType 添加的新功能寫(xiě)到這里
}

可以通過(guò)擴(kuò)展來(lái)擴(kuò)展一個(gè)已有類(lèi)型,使其采納一個(gè)或多個(gè)協(xié)議。在這種情況下,無(wú)論是類(lèi)還是結(jié)構(gòu)體,協(xié)議名字的書(shū)寫(xiě)方式完全一樣:

extension SomeType: SomeProtocol, AnotherProctocol {
    // 協(xié)議實(shí)現(xiàn)寫(xiě)到這里
}

通過(guò)這種方式添加協(xié)議一致性的詳細(xì)描述請(qǐng)參閱利用擴(kuò)展添加協(xié)議一致性

注意

如果你通過(guò)擴(kuò)展為一個(gè)已有類(lèi)型添加新功能,那么新功能對(duì)該類(lèi)型的所有已有實(shí)例都是可用的,即使它們是在這個(gè)擴(kuò)展定義之前創(chuàng)建的。

計(jì)算型屬性

擴(kuò)展可以為已有類(lèi)型添加計(jì)算型實(shí)例屬性和計(jì)算型類(lèi)型屬性。下面的例子為 Swift 的內(nèi)建 Double 類(lèi)型添加了五個(gè)計(jì)算型實(shí)例屬性,從而提供與距離單位協(xié)作的基本支持:

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
print("One inch is \(oneInch) meters")
// 打印 “One inch is 0.0254 meters”
let threeFeet = 3.ft
print("Three feet is \(threeFeet) meters")
// 打印 “Three feet is 0.914399970739201 meters”

這些計(jì)算型屬性表達(dá)的含義是把一個(gè) Double 值看作是某單位下的長(zhǎng)度值。即使它們被實(shí)現(xiàn)為計(jì)算型屬性,但這些屬性的名字仍可緊接一個(gè)浮點(diǎn)型字面值,從而通過(guò)點(diǎn)語(yǔ)法來(lái)使用,并以此實(shí)現(xiàn)距離轉(zhuǎn)換。

在上述例子中,Double1.0 用來(lái)表示“1米”。這就是為什么計(jì)算型屬性 m 返回 self,即表達(dá)式 1.m 被認(rèn)為是計(jì)算 Double1.0。

其它單位則需要一些單位換算。一千米等于 1,000 米,所以計(jì)算型屬性 km 要把值乘以 1_000.00 來(lái)實(shí)現(xiàn)千米到米的單位換算。類(lèi)似地,一米有 3.28024 英尺,所以計(jì)算型屬性 ft 要把對(duì)應(yīng)的 Double 值除以 3.28024 來(lái)實(shí)現(xiàn)英尺到米的單位換算。

這些屬性是只讀的計(jì)算型屬性,為了更簡(jiǎn)潔,省略了 get 關(guān)鍵字。它們的返回值是 Double,而且可以用于所有接受 Double 值的數(shù)學(xué)計(jì)算中:

let aMarathon = 42.km + 195.m
print("A marathon is \(aMarathon) meters long")
// 打印 “A marathon is 42195.0 meters long”

注意

擴(kuò)展可以添加新的計(jì)算型屬性,但是不可以添加存儲(chǔ)型屬性,也不可以為已有屬性添加屬性觀察器。

構(gòu)造器

擴(kuò)展可以為已有類(lèi)型添加新的構(gòu)造器。這可以讓你擴(kuò)展其它類(lèi)型,將你自己的定制類(lèi)型作為其構(gòu)造器參數(shù),或者提供該類(lèi)型的原始實(shí)現(xiàn)中未提供的額外初始化選項(xiàng)。

擴(kuò)展能為類(lèi)添加新的便利構(gòu)造器,但是它們不能為類(lèi)添加新的指定構(gòu)造器或析構(gòu)器。指定構(gòu)造器和析構(gòu)器必須總是由原始的類(lèi)實(shí)現(xiàn)來(lái)提供。

注意

如果你使用擴(kuò)展為一個(gè)值類(lèi)型添加構(gòu)造器,同時(shí)該值類(lèi)型的原始實(shí)現(xiàn)中未定義任何定制的構(gòu)造器且所有存儲(chǔ)屬性提供了默認(rèn)值,那么我們就可以在擴(kuò)展中的構(gòu)造器里調(diào)用默認(rèn)構(gòu)造器和逐一成員構(gòu)造器。 正如在值類(lèi)型的構(gòu)造器代理中描述的,如果你把定制的構(gòu)造器寫(xiě)在值類(lèi)型的原始實(shí)現(xiàn)中,上述規(guī)則將不再適用。

下面的例子定義了一個(gè)用于描述幾何矩形的結(jié)構(gòu)體 Rect。這個(gè)例子同時(shí)定義了兩個(gè)輔助結(jié)構(gòu)體 SizePoint,它們都把 0.0 作為所有屬性的默認(rèn)值:

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()
}

因?yàn)榻Y(jié)構(gòu)體 Rect 未提供定制的構(gòu)造器,因此它會(huì)獲得一個(gè)逐一成員構(gòu)造器。又因?yàn)樗鼮樗写鎯?chǔ)型屬性提供了默認(rèn)值,它又會(huì)獲得一個(gè)默認(rèn)構(gòu)造器。詳情請(qǐng)參閱默認(rèn)構(gòu)造器。這些構(gòu)造器可以用于構(gòu)造新的 Rect 實(shí)例:

let defaultRect = Rect()
let memberwiseRect = Rect(origin: Point(x: 2.0, y: 2.0),
    size: Size(width: 5.0, height: 5.0))

你可以提供一個(gè)額外的接受指定中心點(diǎn)和大小的構(gòu)造器來(lái)擴(kuò)展 Rect 結(jié)構(gòu)體:

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)
    }
}

這個(gè)新的構(gòu)造器首先根據(jù)提供的 centersize 的值計(jì)算一個(gè)合適的原點(diǎn)。然后調(diào)用該結(jié)構(gòu)體的逐一成員構(gòu)造器 init(origin:size:),該構(gòu)造器將新的原點(diǎn)和大小的值保存到了相應(yīng)的屬性中:

let centerRect = Rect(center: Point(x: 4.0, y: 4.0),
    size: Size(width: 3.0, height: 3.0))
// centerRect 的原點(diǎn)是 (2.5, 2.5),大小是 (3.0, 3.0)

注意

如果你使用擴(kuò)展提供了一個(gè)新的構(gòu)造器,你依舊有責(zé)任確保構(gòu)造過(guò)程能夠讓實(shí)例完全初始化。

方法

擴(kuò)展可以為已有類(lèi)型添加新的實(shí)例方法和類(lèi)型方法。下面的例子為 Int 類(lèi)型添加了一個(gè)名為 repetitions 的實(shí)例方法:

extension Int {
    func repetitions(task: () -> Void) {
        for _ in 0..<self {
            task()
        }
    }
}

這個(gè) repetitions(task:) 方法接受一個(gè) () -> Void 類(lèi)型的單參數(shù),表示沒(méi)有參數(shù)且沒(méi)有返回值的函數(shù)。

定義該擴(kuò)展之后,你就可以對(duì)任意整數(shù)調(diào)用 repetitions(task:) 方法,將閉包中的任務(wù)執(zhí)行整數(shù)對(duì)應(yīng)的次數(shù):

3.repetitions({
    print("Hello!")
})
// Hello!
// Hello!
// Hello!

可變實(shí)例方法

通過(guò)擴(kuò)展添加的實(shí)例方法也可以修改該實(shí)例本身。結(jié)構(gòu)體和枚舉類(lèi)型中修改 self 或其屬性的方法必須將該實(shí)例方法標(biāo)注為 mutating,正如來(lái)自原始實(shí)現(xiàn)的可變方法一樣。

下面的例子為 Swift 的 Int 類(lèi)型添加了一個(gè)名為 square 的可變方法,用于計(jì)算原始值的平方值:

extension Int {
    mutating func square() {
        self = self * self
    }
}
var someInt = 3
someInt.square()
// someInt 的值現(xiàn)在是 9

下標(biāo)

擴(kuò)展可以為已有類(lèi)型添加新下標(biāo)。這個(gè)例子為 Swift 內(nèi)建類(lèi)型 Int 添加了一個(gè)整型下標(biāo)。該下標(biāo) [n] 返回十進(jìn)制數(shù)字從右向左數(shù)的第 n 個(gè)數(shù)字:

  • 123456789[0] 返回 9
  • 123456789[1] 返回 8

……以此類(lèi)推。

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
746381295[2]
// 返回 2
746381295[8]
// 返回 7

如果該 Int 值沒(méi)有足夠的位數(shù),即下標(biāo)越界,那么上述下標(biāo)實(shí)現(xiàn)會(huì)返回 0,猶如在數(shù)字左邊自動(dòng)補(bǔ) 0

746381295[9]
// 返回 0,即等同于:
0746381295[9]

嵌套類(lèi)型

擴(kuò)展可以為已有的類(lèi)、結(jié)構(gòu)體和枚舉添加新的嵌套類(lèi)型:

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
        }
    }
}

該例子為 Int 添加了嵌套枚舉。這個(gè)名為 Kind 的枚舉表示特定整數(shù)的類(lèi)型。具體來(lái)說(shuō),就是表示整數(shù)是正數(shù)、零或者負(fù)數(shù)。

這個(gè)例子還為 Int 添加了一個(gè)計(jì)算型實(shí)例屬性,即 kind,用來(lái)根據(jù)整數(shù)返回適當(dāng)?shù)?Kind 枚舉成員。

現(xiàn)在,這個(gè)嵌套枚舉可以和任意 Int 值一起使用了:

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])
// 打印 “+ + - 0 - 0 + ”

函數(shù) printIntegerKinds(_:) 接受一個(gè) Int 數(shù)組,然后對(duì)該數(shù)組進(jìn)行迭代。在每次迭代過(guò)程中,對(duì)當(dāng)前整數(shù)的計(jì)算型屬性 kind 的值進(jìn)行評(píng)估,并打印出適當(dāng)?shù)拿枋觥?/p>

注意

由于已知 number.kindInt.Kind 類(lèi)型,因此在 switch 語(yǔ)句中,Int.Kind 中的所有成員值都可以使用簡(jiǎn)寫(xiě)形式,例如使用 .negative 而不是 Int.Kind.negative。