Swift:枚舉和結(jié)構(gòu)體

Enumerations and Structures

github:Swift基礎(chǔ)實(shí)例
github:SwiftBasicTableView

枚舉
  1. 枚舉
    enum 創(chuàng)建一個(gè)枚舉,與類和所有其他指定的類型一樣,枚舉可以擁有和它相關(guān)聯(lián)的方法:
enum Rank: Int {
    
    case Ace = 1
    case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
    case Jack, Queen, King   
}

讓它包含一個(gè)和它關(guān)聯(lián)的方法 simpleDescription()

enum Rank: Int {
    //enum case must declare a raw value when the preceding raw value is not an integer
    case Ace = 1
    case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
    case Jack, Queen, King
    func simpleDescription() ->String {
        switch self {
        case .Ace:
            return "ace"
        case .Jack:
            return "jack"
        case .Queen:
            return "queen"
        case .King:
            return "king"
        default:
            return String(self.rawValue)
        }
    }
}
let ace = Rank.Ace
let aceRawValue = ace.rawValue          //1
let aceString = ace.simpleDescription() //"ace"
  • 上面代碼中 case Ace = 11Ace 的原始值,稱為rawValue,類型是 Int,后面的枚舉值依次遞增,如Two就是2,依次類推。
  • 枚舉的類型也可以 StringFloat類型,但是除了 Int類型之外,其他類型的rawValue 都不可以遞增,每一個(gè) enum case 都需要指定一個(gè)相應(yīng)類型的值作為它的 rawValue
  1. 枚舉構(gòu)造器
    帶有rawValueenum會(huì)自動(dòng)接收一個(gè)可失敗構(gòu)造器 init?(rawValue:),它根據(jù)枚舉其中一個(gè) raw value,找到合適的case,生成枚舉的實(shí)例對(duì)象;如果沒有匹配到合適的case,則返回nil
let convertRank = Rank(rawValue: 3)
if  convertRank != nil {
      let threeDescription = convertRank.simpleDescription()
      print(threeDescription) //"3"
}
else {
      print("Have no this enum")
}
  1. 枚舉的值
    在枚舉中 case 后的值就是枚舉實(shí)際的值,不僅僅是它們的raw value 的另一種寫法。實(shí)際上,也可以不為枚舉提供 raw value
enum Suit {
    case Spades, Hearts, Diamonds, Clubs
    func simpleDescription() ->String {
        switch self {
        case .Spades:
            return "spades"
        case .Hearts:
            return "hearts"
        case .Diamonds:
            return "diamonds"
        case .Clubs:
            return "clubs"
        }
    }
}
let hearts = Suit.Hearts
// 在這個(gè)枚舉中,我們沒有提供 `raw value` ,當(dāng)強(qiáng)行調(diào)用 rawValue 時(shí),編譯器會(huì)把 `rawValue` 當(dāng)做一個(gè)成員變量,因此會(huì)報(bào)錯(cuò):找不到這個(gè)成員
// let rawValue = hearts.rawValue; 
let heartsDes = hearts.simpleDescription() //"hearts"

注意上面 Hearts 有兩種被引用方式,第一種是在 switch 中,通過簡(jiǎn)寫形式 .Hearts; 第二種是通過 Suit.Hearts,給 hearts賦值。第一種是因?yàn)橥ㄟ^ self 已經(jīng)知道是 Suit,所以可以使用簡(jiǎn)寫形式.Hearts;第二種由于 hearts 沒有明確給出類型,所以只能寫全名。因此,以下的寫法也是對(duì)的:
switch self { case Suit.Hearts:......}
let heartAbb: Suit = .Hearts

  1. 枚舉的關(guān)聯(lián)值(associated values)
    枚舉的 case 值可以存儲(chǔ)一些和它相關(guān)的其他類型的值,稱為關(guān)聯(lián)值(associated values)。
    比如一個(gè)商品的條形碼,條形碼由4部分0-9的數(shù)字組成:第一部分是只有1個(gè)數(shù)字的數(shù)字位;第二部分是5個(gè)數(shù)字的制造位;第三部分是5個(gè)數(shù)字的產(chǎn)品位;第四部分是1個(gè)數(shù)字的校驗(yàn)位。一個(gè)二維碼卻可以包含所有一維碼的信息,同時(shí)還可以包含一些其他信息。我們用枚舉的形式來表現(xiàn)這個(gè)二維碼:
enum Barcode {
    case UPCA(Int, Int, Int, Int)
    case QRCode(String)
}

上面代碼可以理解為:一個(gè)枚舉名字叫 Barcode,這個(gè)枚舉包含一個(gè)值 UPCAUPCA有一個(gè)類型為(Int, Int, Int, Int) 的關(guān)聯(lián)值,或者包含一個(gè)值 QRCode,QRCode 有一個(gè)類型為(String)的關(guān)聯(lián)值。生成一個(gè)含有關(guān)聯(lián)值的枚舉對(duì)象:

var barcode = Barcode.UPCA(9, 72345, 77787, 8)
//barcode 被替換為QRCode(String),barcode 只能存儲(chǔ)其中之一
barcode = .QRCode("abcdef")
switch barcode {
case .UPCA(let numberSystem, let manufacture, let product, let check):
       print("UPC-A: \(numberSystem) \(manufacture) \(product) \(check)")
case .QRCode(let productCode):
       print("QR Code: \(productCode)")
}
//prints "QR Code: abcdef"

如果關(guān)聯(lián)值的類型都是常量(constant)變量(variable),那么只需要在 case 前寫一個(gè) letvar ,就可以了:

switch barcode {
case let .UPCA(numberSystem, manufacture, product, check):
       print("UPC-A: \(numberSystem) \(manufacture) \(product) \(check)")
case let .QRCode(productCode):
       print("QR Code: \(productCode)")
}
//prints "QR Code: abcdef"
結(jié)構(gòu)體
  • 用關(guān)鍵字 struct 創(chuàng)建一個(gè)結(jié)構(gòu)體。
    結(jié)構(gòu)體(struct) 和 類(class)有很多相似的地方,也包含有屬性、方法和初始化構(gòu)造器。主要來看一下它們的不同點(diǎn):
  • class 有繼承,struct 沒有
  • runtime 期間,根據(jù) Type casting (類型轉(zhuǎn)換),可以得知一個(gè)實(shí)例( instance)所屬于的類
  • class 有析構(gòu)函數(shù),struct 沒有
  • class 可以使用 ARC

最重要的,結(jié)構(gòu)體屬于值類型,在代碼中傳遞的時(shí)候,每次都會(huì)被復(fù)制(copy)一份,而類是通過引用(reference)傳遞的:

struct Card {
    var score : Int
}

let cart      = Cart(score: 3)
var varCart   = cart
varCart.score = 5
print(cart.score) // 3
print(varCart.score) // 5

可以看到,我們把對(duì)象 cart 賦值給 varCart 后,修改 varCart 的屬性值,并不會(huì)對(duì) cart 的屬性值造成影響。這和下面的 class 完全不同:

class testInit {
    
    var number = 0
    var point = 9
}

let testI    = testInit()
let testII   = testI
testII.point = 8
print(testI.point) // 8

當(dāng)我們把對(duì)象 testI 賦值給 testII 后,修改 testII 的屬性 point,由于類是引用類型(相應(yīng)說明參考概念解釋),

通過下面的代碼,我們來認(rèn)識(shí) struct 中很重要的一個(gè)概念:成員構(gòu)造器。(該構(gòu)造器的說明請(qǐng)參考 概念解釋)

struct Card {
    var rank : Rank
    var suit : Suit    

    func simpleDescription()-> String {
        return "The \(rank.simpleDescription()) of \(suit.simpleDescription())"
    }
}
let threeOfSpades = Card(rank: .Three, suit: .Spades)
let threeDes = threeOfSpades.simpleDescription() //"The 3 of spades"

上面的代碼中,我們使用了函數(shù) Card(_: , _: ) 生成一個(gè)對(duì)象,此函數(shù)是 struct 自動(dòng)接收的,稱為 成員構(gòu)造器 (Memberwise initializer)

需要注意到是,上面結(jié)構(gòu)體內(nèi)的兩個(gè)屬性 ranksuit 在聲明時(shí)并沒有初始化,而是在生成 threeOfSpades 實(shí)例對(duì)象的時(shí)候才初始化,因此,結(jié)構(gòu)體只接收一個(gè)成員構(gòu)造器。如果這兩個(gè)屬性在聲明的時(shí)候已經(jīng)初始化,那么,結(jié)構(gòu)體將接收兩個(gè)構(gòu)造器:Card()Card(_: , _: ) 。少初始化任何一個(gè)屬性,都只會(huì)接收一個(gè)構(gòu)造器:Card(_: , _: )

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,517評(píng)論 6 539
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,087評(píng)論 3 423
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,521評(píng)論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,493評(píng)論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,207評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,603評(píng)論 1 325
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,624評(píng)論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,813評(píng)論 0 289
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,364評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,110評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,305評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,874評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,532評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,953評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,209評(píng)論 1 291
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,033評(píng)論 3 396
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,268評(píng)論 2 375

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