Day15 擴(kuò)展(Extensions)

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

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

注意:
擴(kuò)展可以為一個(gè)類型添加新的功能,但是不能重寫已有的功能捏雌。

1跃赚、擴(kuò)展語法

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

    class SomeType {
        
    }
    
    extension SomeType {
        // 為 SomeType 添加的新功能寫到這里
    }
    
    //可以通過擴(kuò)展來擴(kuò)展一個(gè)已有類型性湿,使其采納一個(gè)或多個(gè)協(xié)議:
    extension SomeType: SomeProtocol, AnotherProctocol {
        // 協(xié)議實(shí)現(xiàn)寫到這里
    }

2满败、計(jì)算型屬性

擴(kuò)展可以為已有類型添加計(jì)算型實(shí)例屬性和計(jì)算型類型屬性:
下面的例子為 Swift 的內(nèi)建 Double 類型添加了五個(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ì)算型屬性葫录,為了更簡潔,省略了 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ǔ)型屬性少孝,也不可以為已有屬性添加屬性觀察器继低。

3、構(gòu)造器

擴(kuò)展可以為已有類型添加新的構(gòu)造器

下面的例子定義了一個(gè)用于描述幾何矩形的結(jié)構(gòu)體 Rect 稍走。
這個(gè)例子同時(shí)定義了兩個(gè)輔助結(jié)構(gòu)體 Size 和 t ,它們都把 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()
    }
    
    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)造器來擴(kuò)展 Rect 結(jié)構(gòu)體:
    pextension 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)
        }}</pre>

這個(gè)新的構(gòu)造器首先根據(jù)提供的 center 和 size 的值計(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)

4幻件、方法

擴(kuò)展可以為已有類型添加新的實(shí)例方法和類型方法绰沥。

下面的例子為 Int 類型添加了一個(gè)名為 repetitions 的實(shí)例方法:

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

這個(gè) repetitions(task:) 方法接受一個(gè) () -> Void 類型的單參數(shù)揪利,表示沒有參數(shù)且沒有返回值的函數(shù)狠持。
定義該擴(kuò)展之后,你就可以對(duì)任意整數(shù)調(diào)用 repetitions(task:) 方法甜刻,將閉包中的任務(wù)執(zhí)行整數(shù)對(duì)應(yīng)的次數(shù):

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

可以使用尾隨閉包讓調(diào)用更加簡潔:
3.repetitions {
print("Goodbye!")
}
// Goodbye!
// Goodbye!
// Goodbye!

可變實(shí)例方法

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

    //下面的例子為 Swift 的 Int 類型添加了一個(gè)名為 square 的可變方法蜕径,用于計(jì)算原始值的平方值:
    extension Int {
        mutating func square() {
            self = self * self
        }
    }
    var someInt = 3 someInt.square()
    // someInt 的值現(xiàn)在是 9*/

5兜喻、下標(biāo)

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

    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
    
    
    如果該 Int 值沒有足夠的位數(shù)肮疗,即下標(biāo)越界族吻,那么上述下標(biāo)實(shí)現(xiàn)會(huì)返回 0 超歌,猶如在數(shù)字左邊自動(dòng)補(bǔ) 0 :
    
    746381295[9]
    // 返回 0蒂教,即等同于:
    0746381295[9]
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市懊悯,隨后出現(xiàn)的幾起案子炭分,更是在濱河造成了極大的恐慌,老刑警劉巖捧毛,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件师痕,死亡現(xiàn)場離奇詭異而账,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)泞辐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門狠裹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來汽烦,“玉大人莉御,你說我怎么就攤上這事‰咕保” “怎么了煮岁?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長步氏。 經(jīng)常有香客問我徒爹,道長界阁,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任精续,我火速辦了婚禮重付,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘删掀。我一直安慰自己披泪,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著缚够,像睡著了一般谍椅。 火紅的嫁衣襯著肌膚如雪埂伦。 梳的紋絲不亂的頭發(fā)上沾谜,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音媳否,去河邊找鬼篱竭。 笑死吃媒,一個(gè)胖子當(dāng)著我的面吹牛吕喘,可吹牛的內(nèi)容都是我干的氯质。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼呢灶,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了隧期?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎鹏浅,沒想到半個(gè)月后屏歹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體季希,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了囚枪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡括勺,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出乱豆,到底是詐尸還是另有隱情宛裕,我是刑警寧澤揩尸,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布坟瓢,位于F島的核電站折联,受9級(jí)特大地震影響怀浆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一奠伪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧究履,春花似錦最仑、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽梆奈。三九已至,卻和暖如春鳖轰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背臭觉。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來泰國打工揩懒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人智亮。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像亦鳞,于是被迫代替她去往敵國和親遭笋。 傳聞我的和親對(duì)象是個(gè)殘疾皇子瓦呼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young閱讀 3,802評(píng)論 1 10
  • 國家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說閱讀 10,958評(píng)論 6 13
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理饲宿,服務(wù)發(fā)現(xiàn)瘫想,斷路器,智...
    卡卡羅2017閱讀 134,651評(píng)論 18 139
  • Swift屬性 Swift屬性將值跟特定的類车吹,結(jié)構(gòu)體,枚舉關(guān)聯(lián)馒吴。分為存儲(chǔ)屬性和計(jì)算屬性饮戳,通常用于特定類型的實(shí)例扯罐。屬...
    小小廚師閱讀 854評(píng)論 0 0
  • 作者:王維 渭城朝雨浥輕塵,客舍青青柳色新秸歧。 勸君更盡一杯酒键菱,西出陽關(guān)無故人拭抬。 「注解」 這是唐代一首極為著名的送...
    開心滿滿閱讀 487評(píng)論 0 0