Spec-Zone .ru
спецификации, руководства, описания, API

Библиотека разработчика XCode

Разработчик

Swift язык программирования

iBook
На этой странице

Вложенные типы

Перечисления часто создаются для поддержки определенного класса или функциональности структуры. Точно так же может быть удобно определить служебные классы и структуры просто для использования в контексте более составного типа. Для выполнения этого 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 быть сохраненным сознательно коротким, потому что их имена естественно квалифицированы контекстом, в котором они определяются.