Статическая переменная
Суть
Статическая переменная принадлежит типу, а не экземпляру: одна на всех объектов класса/структуры, живёт до конца работы программы. В Swift это static let / static var внутри типа. Ключевое, что нужно знать: инициализируется она не при старте программы, а лениво.
Как это работает в Swift
- Ленивая и потокобезопасная инициализация: значение вычисляется при первом обращении, ровно один раз, под
swift_once. Именно поэтомуstatic let shared = Service()— корректный потокобезопасный синглтон безdispatch_once. staticvsclass:static varнельзя переопределить в подклассе;class var— можно, но только вычисляемое (хранимыхclass varнет).- Локальных static нет: в Swift нельзя объявить
static varвнутри функции, как в C. Идиома — вложенный тип-хранилище. - Swift 6:
static var— это глобальное изменяемое состояние, и без изоляции (@MainActor) илиnonisolated(unsafe)это ошибка компиляции.static letдопустим, если типSendable.
struct Config {
static let value: Int = { print("computed"); return 42 }()
}
print("start")
print(Config.value) // computed, затем 42
print(Config.value) // 42 — инициализатор не повторяется
final class Analytics: Sendable {
static let shared = Analytics() // синглтон: ленивый и потокобезопасный
@MainActor static var eventCount = 0 // Swift 6: без изоляции — ошибка
private init() {}
}
func nextID() -> Int {
// static var n = 0 // ошибка: static только внутри типа
enum Storage { nonisolated(unsafe) static var n = 0 } // идиома-замена
Storage.n += 1
return Storage.n
}
Вывод программы: start, computed, 42, 42 — «computed» печатается один раз и только после start.
Где применяют
- Константы и пространства имён:
enum Constants { static let pageSize = 20 }. - Синглтоны и кэши (
static let shared). - Кеширование дорогих объектов:
static let formatter = DateFormatter()— создаётся один раз вместо каждого вызова.
На что смотрит интервьюер
Ответ «инициализируется при запуске программы» — ошибка. Правильно: лениво, один раз, потокобезопасно. Бонус — знать, почему это даёт бесплатный синглтон и что меняет Swift 6.