Swift 程式語言 — Nested Types

讓我們來看看如何在 Swift 中使用內嵌類型吧!

Jeremy Xue
Jeremy Xue ‘s Blog
4 min readOct 27, 2019

--

Photo by Declan Lopez on Unsplash

前言:

通常創建 enum 來支持特定 classstruct 的功能。同樣的,它也可以在更加複雜的類型環境中方便的定義 classstruct。為此,Swift 使你能夠定義內嵌類型(Nested Types),藉此在支持類型中定義嵌套 enumclass、或 struct

要將一個類型內嵌到另一個類型中,請在其支持類型的大括號內寫入其定義。類型可以被內嵌到所需的多個層級。

|內嵌類型的操作

下面的範例定義了一個稱為 BlackjackCardstruct,該 struct 可以模擬 21 點遊戲中使用的撲克牌。BlackjackCard 包含兩個內嵌的 enum 類型,分別為 SuitRank

在 21 點中,Ace 卡的值是 1 或 11。此功能由稱為 Valuesstruct 表示,其內嵌在 Rank enum 中:

其中 Suitenum 描述了四種常見的撲克牌花色,以及代表其符號的原始 Character 值。

Rankenum 描述了 13 種可能的撲克牌等級,以及代表其面值的原始 Int 值。

如上所述,Rank enum 定義了自己的另一個內嵌 struct,稱為 Values。這個 struct 封裝了以下內容:大多數牌具有一個值,但是 Ace 牌具有兩個值。而 Values 結構定義了兩個屬性來表示這點:

  • first,類型為 Int
  • second,類型為 Int?

Rank 還定義了一個計算屬性 values,它返回 Values 的實例。該計算屬性考慮到牌的 rank,並且根據其 rank 使用適當的值初始化一個新的 Values 實例。它對 jackqueenkingace 使用特殊值。對於數字牌,它使用 rank 的原始 Int 值。

BlackjackCard struct 本身具有兩個屬性 ranksuit。它還定義了一個稱為 description 的計算屬性,該屬性使用存儲在 ranksuit 來建構卡牌的名稱和值的描述。description 屬性使用 optional binding 去檢查是否有第二個值要顯示,如果是,則為第二個值插入額外的描述細節。

因為 BlackjackCard 是沒有自定義初始化器的 struct,它具有隱式的成員初始化器,如 struct 類型中的 Memberwise Initializers for Structure Types 所述。你可以使用初始化器初始化一個稱為 theAceOfSpades 的新常數:

即使 RankSuit 內嵌在 BlackjackCard 中,它們的類型也可以從上下文中被推斷出來,因此,這個實例的初始化能透過其 case 名稱(.ace.spades)來引用 enum case。在上面的範例中,description 屬性正確的回報黑桃 Ace 的值為 111

|引用內嵌類型

要在其定義上下文之外使用內嵌類型,請在內嵌在其中的類型名為作為其名稱的前綴:

對於上面的範例,可以使 SuitRankValues 的名稱故意保持簡短,因為他們的名稱自然受到定義他們的上下文限制。

--

--

Jeremy Xue
Jeremy Xue ‘s Blog

Hi, I’m Jeremy. [好想工作室 — iOS Developer]