Ответ
Ключевое слово static в Swift объявляет члены типа (свойства и методы), которые принадлежат самому типу, а не какому-либо его экземпляру. Доступ к ним осуществляется через имя типа.
Основное использование:
class Logger {
// Статическое свойство — общее для всего типа (аналог "классовой переменной")
static let shared = Logger()
static var logLevel: LogLevel = .info
// Статический метод — вызывается на типе, а не на экземпляре
static func log(_ message: String) {
print("[\(logLevel)] \(message)")
}
private init() {} // Скрытый конструктор для синглтона
}
// Использование БЕЗ создания экземпляра класса Logger
Logger.logLevel = .debug
Logger.log("Приложение запущено") // Вывод: [debug] Приложение запущено
let loggerInstance = Logger.shared // Доступ к синглтону через static свойство
Важные детали:
- В классах: Объявление с
staticявляется синонимомfinal class. Такие члены не могут быть переопределены в подклассах.class Vehicle { static func description() { print("Транспортное средство") } class func adjustableDescription() { print("Настраиваемое описание") } // Можно переопределить } class Car: Vehicle { // override static func description() { } // Ошибка компиляции: нельзя переопределить override class func adjustableDescription() { print("Автомобиль") } // OK } - В структурах и перечислениях:
staticиспользуется без ограничений, так как эти типы не поддерживают наследование. - Область видимости: Статические свойства инициализируются лениво и гарантированно один раз (потокобезопасно), что делает их удобными для реализации синглтонов и shared-ресурсов.
Ответ 18+ 🔞
Слушай, вот этот твой static в Swift — это ж как та общая заначка на всех, которую спиздить нельзя, потому что она приколочена к полу, блядь. Ну, то есть, это члены, которые принадлежат самому типу, а не какому-то отдельному экземпляру. Обращаешься к ним прямо по имени типа, даже создавать ничего не надо. Красота, ёпта!
Смотри, как это работает, на живом примере:
class Logger {
// Вот это статическое свойство — общее на всю твою программу. Классовая переменная, блядь.
static let shared = Logger()
static var logLevel: LogLevel = .info
// А это статический метод. Вызываешь на классе, и всё, ни одного экземпляра.
static func log(_ message: String) {
print("[(logLevel)] (message)")
}
private init() {} // Приватный конструктор, чтобы синглтон был синглтоном, а не распиздяйством.
}
// Используем БЕЗ создания экземпляра, в натуре!
Logger.logLevel = .debug
Logger.log("Приложение запущено") // Выведет: [debug] Приложение запущено
let loggerInstance = Logger.shared // А вот так получаешь тот самый единственный экземпляр через static.
А теперь важные нюансы, чтобы не обосраться:
- В классах: Когда ты пишешь
static— это всё, приехали. Это какfinal class. Переопределить эту хуйню в подклассе нельзя, ни хера. Хоть тресни.class Vehicle { static func description() { print("Транспортное средство") } class func adjustableDescription() { print("Настраиваемое описание") } // А вот это — можно переопределить! } class Car: Vehicle { // override static func description() { } // Ошибка компиляции! Нельзя, блядь! Final, ёпта! override class func adjustableDescription() { print("Автомобиль") } // А это — пожалуйста, на здоровье. } - В структурах и перечислениях: Тут вообще красота, потому что наследования нет. Пихай
staticкуда хочешь, и ни у кого вопросов не будет. - Область видимости и безопасность: Вот это вообще охуенно. Статические свойства инициализируются лениво и гарантированно один раз, да ещё и потокобезопасно. Идеально, чтобы делать синглтоны или всякие общие ресурсы, которые на всех одни. Никаких гонок, никакого пиздеца.