Видеокурсы по изучению языка программирования Swift. Подробнее

Соединение нескольких уровней ОП

Если вы нашли опечатку в тексте, выделите ее и нажмите CTRL + ENTER.

Вы можете соединить несколько уровней опциональных последовательностей вместе для того, чтобы пробраться до свойств, методов, сабскриптов, которые находятся глубже в модели. Однако многоуровневые опциональные последовательности не добавляют новых уровней опциональности к возвращаемым значениям:

Скажем другими словами:

  • Если тип, который вы пытаетесь получить не опциональный, то он станет опциональным из-за опциональной последовательности.
  • Если тип, который вы пытаетесь получить, уже опциональный, то более опциональным он уже не станет, даже по причине опциональной последовательности.

Таким образом:

  • Если вы пытаетесь получить значение типа Int через опциональную последовательность, то получите Int?, и это не будет зависеть от того, сколько уровней в опциональной последовательности задействовано.
  • Аналогично, если вы попытаетесь получить значение типа Int? через опциональную последовательность, то вы получите Int?, что опять таки не зависит от количества уровней, которые задействованы в опциональной последовательности.

Пример ниже пробует получить доступ к свойству street свойства address свойства residence экземпляра john. Здесь задействовано два уровня опциональной последовательности для того, чтобы соединить свойства residence и address, оба из которых опционального типа:

if let johnsStreet = john.residence?.address?.street {
    print("John's street name is \(johnsStreet).")
} else {
    print("Unable to retrieve the address.")
}
// Выведет "Unable to retrieve the address."

Значение john.residence на данный момент содержит корректный экземпляр класса Residence. Однако значение john.residence.address равно nil. Из-за этого вызов john.residence?.address?.street проваливается.

Обратите внимание, что в примере выше вы пытаетесь получить значение свойства street. Тип этого свойства String?. Возвращаемое значение john.residence?.address?.street так же String?, даже если два уровня опциональной последовательности применены в дополнение к опциональному типу самого свойства.

Если вы установите фактический экземпляр класса Address как значение для john.residence.address и установите фактическое значение для свойства street, то вы можете получить доступ к значению свойства street через многоуровневую опциональную последовательность (цепочку):

let johnsAddress = Address()
johnsAddress.buildingName = "The Larches"
johnsAddress.street = "Laurel Street"
john.residence!.address = johnsAddress
 
if let johnsStreet = john.residence?.address?.street {
    print("John's street name is \(johnsStreet).")
} else {
    print("Unable to retrieve the address.")
}
// Выведет "John's street name is Laurel Street."

Обратите внимание на использование восклицательного знака внутри john.residence!.address. Свойство john.residence имеет опциональный тип, так что вам нужно развернуть его фактическое значение при помощи восклицательного знака до того, как вы попытаетесь получить доступ к свойству address свойства residence.

Swift: 
3.0