Static variable

See also: Reference – static items

Static variables, also called global variables, are items that contain a value that is always accessible; it is never created or destroyed. Static variables can have a destructor, but that destructor is never run.

Unlike constants, static variables have a fixed memory location. Their initial value is const-evaluated at compile time and has a 'static lifetime.

A static variable can be declared within a function, which makes it inaccessible outside of the function; however, this doesn't affect its lifetime (it isn't dropped at the end of the function).

LimitationsEdit

Static variables must be thread safe. This means that their type must implement the Sync  trait. For example, Rc  or RefCell  can't be used in a static variable as they are not thread safe - having multiple threads access them at once causes a data race.

Static variables can refer to other static variables, but only through a reference, not by value.

Constants can't refer to a static variable.

ExampleEdit

fn get(n: usize) -> &'static str {
    static STRS: &[&str] = &[
        "zero", "one", "two", "three", "four",
        "five", "six", "seven", "eight", "nine",
    ];
    STRS[n]
}


Using statics or constantsEdit

It can be confusing whether or not you should use a constant item or a static item. Constants should, in general, be preferred over statics unless one of the following are true:

  • Large amounts of data are being stored
  • The single-address property of statics is required.
  • Interior mutability is required.

Mutable static variablesEdit

Static variables can be mutable. Since Rust can't prove the absence of data races when accessing a static mutable variable, accessing it is unsafe.

Using static mutable variables is discouraged, since they are not only unsafe, but also very difficult to use correctly: Without synchronization primitives such as Mutex , it is almost impossible to prove that no data races occur. They are likely to be removed in a future version of Rust; if you need unsafe static mutability use UnsafeCell .

ExampleEdit

static mut FOO: i32 = 40;

pub fn add_two() -> i32 {
    unsafe {
        FOO += 2;
        FOO
    }
}


Note that this is unsound: If add_two() is called from multiple threads, the access of FOO is racy.

A solution is to use a synchronization primitive such as Mutex<i32>  or AtomicI32 . Since these have interior mutability, we can use a safe, immutable static variable:

static FOO: AtomicI32 = AtomicI32::new(40);

pub fn add_two() -> i32 {
    let prev = FOO.fetch_add(2, Ordering::SeqCst);
    prev + 2
}