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

嵌套類型


1.0 翻譯:Lin-H 校對:shinyzhu

2.0 翻譯+校對:SergioChan

2.1 校對:shanks,2015-11-01

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

4.0 翻譯+校對:EyreFree 2017-10-19

4.1 翻譯+校對:mylittleswift

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

枚舉常被用于為特定類或結構體實現(xiàn)某些功能。類似地,枚舉可以方便的定義工具類或結構體,從而為某個復雜的類型所使用。為了實現(xiàn)這種功能,Swift 允許你定義嵌套類型,可以在支持的類型中定義嵌套的枚舉、類和結構體。

要在一個類型中嵌套另一個類型,將嵌套類型的定義寫在其外部類型的 {} 內(nèi),而且可以根據(jù)需要定義多級嵌套。

嵌套類型實踐

下面這個例子定義了一個結構體 BlackjackCard(二十一點),用來模擬 BlackjackCard 中的撲克牌點數(shù)。BlackjackCard 結構體包含兩個嵌套定義的枚舉類型 SuitRank

BlackjackCard 中,Ace 牌可以表示 1 或者 11,Ace 牌的這一特征通過一個嵌套在 Rank 枚舉中的結構體 Values 來表示:

struct BlackjackCard {

    // 嵌套的 Suit 枚舉
    enum Suit: Character {
        case spades = "?", hearts = "?", diamonds = "?", clubs = "?"
    }

    // 嵌套的 Rank 枚舉
    enum Rank: Int {
        case two = 2, three, four, five, six, seven, eight, nine, ten
        case jack, queen, king, ace
        struct Values {
            let first: Int, second: Int?
        }
        var values: Values {
            switch self {
            case .ace:
                return Values(first: 1, second: 11)
            case .jack, .queen, .king:
                return Values(first: 10, second: nil)
            default:
                return Values(first: self.rawValue, second: nil)
            }
        }
    }

    // BlackjackCard 的屬性和方法
    let rank: Rank, suit: Suit
    var description: String {
        var output = "suit is \(suit.rawValue),"
        output += " value is \(rank.values.first)"
        if let second = rank.values.second {
            output += " or \(second)"
        }
        return output
    }
}

Suit 枚舉用來描述撲克牌的四種花色,并用一個 Character 類型的原始值表示花色符號。

Rank 枚舉用來描述撲克牌從 Ace~10,以及 J、Q、K,這 13 種牌,并用一個 Int 類型的原始值表示牌的面值。(這個 Int 類型的原始值未用于 AceJ、Q、K4 種牌。)

如上所述,Rank 枚舉在內(nèi)部定義了一個嵌套結構體 Values。結構體 Values 中定義了兩個屬性,用于反映只有 Ace 有兩個數(shù)值,其余牌都只有一個數(shù)值:

  • first 的類型為 Int
  • second 的類型為 Int?,或者說“可選 Int

Rank 還定義了一個計算型屬性 values,它將會返回一個 Values 結構體的實例。這個計算型屬性會根據(jù)牌的面值,用適當?shù)臄?shù)值去初始化 Values 實例。對于 J、Q、K、Ace 這四種牌,會使用特殊數(shù)值。對于數(shù)字面值的牌,使用枚舉實例的 Int 類型的原始值。

BlackjackCard 結構體擁有兩個屬性—— ranksuit。它也同樣定義了一個計算型屬性 description,description 屬性用 ranksuit 中的內(nèi)容來構建對撲克牌名字和數(shù)值的描述。該屬性使用可選綁定來檢查可選類型 second 是否有值,若有值,則在原有的描述中增加對 second 的描述。

因為 BlackjackCard 是一個沒有自定義構造器的結構體,在結構體的逐一成員構造器中可知,結構體有默認的成員構造器,所以你可以用默認的構造器去初始化新常量 theAceOfSpades

let theAceOfSpades = BlackjackCard(rank: .ace, suit: .spades)
print("theAceOfSpades: \(theAceOfSpades.description)")
// 打印 “theAceOfSpades: suit is ?, value is 1 or 11”

盡管 RankSuit 嵌套在 BlackjackCard 中,但它們的類型仍可從上下文中推斷出來,所以在初始化實例時能夠單獨通過成員名稱(.ace.spades)引用枚舉實例。在上面的例子中,description 屬性正確地反映了黑桃 A 牌具有 111 兩個值。

引用嵌套類型

在外部引用嵌套類型時,在嵌套類型的類型名前加上其外部類型的類型名作為前綴:

let heartsSymbol = BlackjackCard.Suit.hearts.rawValue
// 紅心符號為 “?”

對于上面這個例子,這樣可以使 Suit、RankValues 的名字盡可能的短,因為它們的名字可以由定義它們的上下文來限定。