Вложенные типы
Перечисления часто создаются для поддержки определенного класса или функциональности структуры. Точно так же может быть удобно определить служебные классы и структуры просто для использования в контексте более составного типа. Для выполнения этого Swift позволяет Вам определить вложенные типы, посредством чего Вы вкладываете перечисления поддержки, классы и структуры в определении типа, который они поддерживают.
Для вложения типа в другом типе запишите его определение во внешних фигурных скобках типа, который он поддерживает. Типы могут быть вложены к стольким уровням, сколько требуются.
Вложенные типы в действии
Пример ниже определяет вызванную структуру BlackjackCard
, который моделирует игральную карту, как используется в игре Блэк джека. BlackJack
структура содержит два вложенных вызванные типа перечисления Suit
и Rank
.
В Блэк джеке Первоклассные карты имеют значение или один или одиннадцать. Эта функция представлена вызванной структурой Values
, который вкладывается в Rank
перечисление:
struct BlackjackCard {
// nested Suit enumeration
enum Suit: Character {
case Spades = "♠", Hearts = "♡", Diamonds = "♢", Clubs = "♣"
}
// nested Rank enumeration
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 properties and methods
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
перечисление описывает тринадцать возможных разрядов игральной карты, вместе с сырыми данными Int
значение для представления их номинальной стоимости. (Эти сырые данные Int
значение не используется для Джека, Королевы, Короля, и Первоклассных карт.)
Как упомянуто выше, Rank
перечисление определяет дальнейшую вложенную собственную структуру, вызванный Values
. Эта структура инкапсулирует факт, что большинство карт имеет одно значение, но Первоклассная карта имеет два значения. Values
структура определяет два свойства для представления этого:
first
, из типаInt
second
, из типаInt?
, или “дополнительныйInt
”
Rank
также определяет вычисленное свойство, values
, который возвращает экземпляр Values
структура. Это вычисленное свойство рассматривает разряд карты и инициализирует новое Values
экземпляр с надлежащими значениями на основе его разряда. Это использует специальные значения для Jack
, Queen
, King
, и Ace
. Для числовых карт это использует сырые данные разряда Int
значение.
BlackjackCard
сама структура имеет два свойства —rank
и suit
. Это также определяет вычисленное вызванное свойство description
, который использует значения, сохраненные в rank
и suit
создавать описание имени и значение карты. description
свойство использует дополнительную привязку, чтобы проверить, существует ли второе значение для отображения, и если так, вставляет подробность дополнительного описания для того второго значения.
Поскольку BlackjackCard
структура без пользовательских инициализаторов, она имеет неявный memberwise инициализатор, как описано в Инициализаторах Memberwise для Типов Структуры. Можно использовать этот инициализатор для инициализации новой вызванной константы theAceOfSpades
:
let theAceOfSpades = BlackjackCard(rank: .Ace, suit: .Spades)
println("theAceOfSpades: \(theAceOfSpades.description)")
// prints "theAceOfSpades: suit is ♠, value is 1 or 11"
Даже при том, что Rank
и Suit
вкладываются в BlackjackCard
, их тип может быть выведен из контекста, и таким образом, инициализация этого экземпляра в состоянии относиться к элементам перечисления их именами элемента (.Ace
и .Spades
) один. В примере выше, description
свойство правильно сообщает, что Туз Лопат имеет значение 1
или 11
.
Что касается вложенных типов
Для использования вложенного типа за пределами его контекста определения снабдите префиксом его имя имя типа, в котором оно вкладывается:
let heartsSymbol = BlackjackCard.Suit.Hearts.rawValue
// heartsSymbol is "♡"
Для примера выше, это включает имена Suit
, Rank
, и Values
быть сохраненным сознательно коротким, потому что их имена естественно квалифицированы контекстом, в котором они определяются.