Видеокурсы по изучению языка программирования 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."

В этом примере попытка установить свойство address свойства john.residence будет успешной, потому что значение john.residence в настоящее время содержит действующий экземпляр Address.

Swift: 
4.0