В чем разница между lazy stored property и computed property в Swift?

«В чем разница между lazy stored property и computed property в Swift?» — вопрос из категории Swift Core, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Оба типа свойств не хранят значение изначально, но механизм и цель их работы различны.

Аспект Lazy Stored Property (lazy var) Computed Property (var { })
Назначение Отложенная инициализация для оптимизации (тяжелые вычисления или зависимости). Предоставление значения «на лету» на основе других свойств.
Хранение Является stored property. Вычисляет значение один раз при первом обращении и сохраняет его. Не хранит значение. Вычисляет значение каждый раз при обращении.
Синтаксис Использует замыкание для вычисления начального значения: lazy var name = { ... }() Использует getter (и опционально setter): var name: Type { get { ... } set { ... } }
Тип (let/var) Только var (значение устанавливается после инициализации). Может быть var (с get/set) или let (только get, read-only).
Зависимости Может обращаться к self и другим свойствам экземпляра, так как вычисляется позже. Getter может использовать другие свойства. Setter часто изменяет другие stored properties.

Пример lazy property:

class DataLoader {
    lazy var cachedData: [String] = {
        print("Performing expensive loading...")
        return loadDataFromDisk() // Выполнится только один раз
    }()
}
let loader = DataLoader()
print(loader.cachedData) // "Performing expensive loading..." затем данные
print(loader.cachedData) // Данные возвращаются мгновенно (значение сохранено)

Пример computed property:

struct Rectangle {
    var width: Double
    var height: Double

    var area: Double { // Вычисляется каждый раз
        return width * height
    }

    var description: String { // Read-only computed property
        return "Rectangle (width)x(height)"
    }
}
var rect = Rectangle(width: 5, height: 10)
print(rect.area) // 50.0
rect.width = 10
print(rect.area) // 100.0 — вычислено заново

Вывод: Используйте lazy для дорогих или не всегда нужных вычислений, computed — для значений, производных от текущего состояния объекта.