Ключевое слово static

Статический элемент — это значение, которое действительно в течение всего времени выполнения вашей программы (время жизни 'static).

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

Статические элементы не вызывают drop в конце программы.

Существует два типа статических элементов: объявленные с ключевым словом mut и без него.

Статические элементы не могут быть перемещены: ⓘ

#![allow(unused)]
fn main() {
static VEC: Vec<u32> = vec![];

fn move_vec(v: Vec<u32>) -> Vec<u32> {
    v
}

// Эта строка вызывает ошибку
move_vec(VEC);
}

Простые статические элементы (без mut)

Доступ к неизменяемым статическим элементам считается безопасным, но применяются некоторые ограничения. Наиболее notably, тип статического значения должен реализовывать трейт Sync, что исключает контейнеры с внутренней изменчивостью, такие как RefCell. См. Справочник для получения более подробной информации.

#![allow(unused)]
fn main() {
static FOO: [i32; 5] = [1, 2, 3, 4, 5];

let r1 = &FOO as *const _;
let r2 = &FOO as *const _;
// С строго доступным только для чтения статиком ссылки будут иметь тот же адрес
assert_eq!(r1, r2);
// Статический элемент может использоваться так же, как переменная, во многих случаях
println!("{FOO:?}");
}

Изменяемые статические элементы (с mut)

Если статический элемент объявлен с ключевым словом mut, то программе разрешено его изменять. Однако доступ к изменяемым статикам может вызвать неопределённое поведение различными способами, например, из-за гонки данных в многопоточном контексте. Как таковой, весь доступ к изменяемым статикам требует блока unsafe.

Когда это возможно, часто лучше использовать неизменяемый статик с типом внутренней изменчивости, таким как Mutex, OnceLock или атомарный тип.

Несмотря на их небезопасность, изменяемые статики необходимы во многих контекстах: они могут использоваться для представления глобального состояния, разделяемого всей программой, или в блоках extern для привязки к переменным из библиотек C.

В блоке extern:

#![allow(unused)]
fn main() {
unsafe extern "C" {
    static mut ERROR_MESSAGE: *mut std::os::raw::c_char;
}
}

На изменяемые статики, как и на простые статики, распространяются некоторые ограничения. См. Справочник для получения более подробной информации.