Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

static Variables

Goal of This Episode

Understand the difference between static and const, and why you should almost never use static mut.

Concept

static vs const

Chapter 2 covered const — compile-time constants whose values get embedded directly wherever they’re used. static looks similar, but there’s one fundamental difference: a static variable has a fixed memory address.

static GREETING: &str = "Hello, world!";
static MAX_SIZE: usize = 1024;

fn main() {}

Most of the time const is enough. Use static only when you need a fixed memory address (e.g. to hand to a C function).

static mut

Rust allows mutable statics — but both reading and writing require unsafe:

static mut COUNTER: i32 = 0;

fn increment() {
    unsafe { COUNTER += 1; }
}

fn main() {}

Why the unsafe? Because a static is globally shared — multiple Threads reading and writing it at once is a data race.

static mut should almost never be used. Modern Rust has better alternatives:

  • A simple counter → AtomicI32, AtomicBool.
  • Complex mutable global state → Mutex<T> (paired with static).
  • Lazy initialization → LazyLock (next episode).

Example Code

use std::sync::atomic::{AtomicI32, Ordering};

// const: value embedded at use sites
const MAX: i32 = 100;

// static: has a fixed address
static GREETING: &str = "Hello!";

// atomic instead of static mut
static COUNTER: AtomicI32 = AtomicI32::new(0);

fn increment() {
    COUNTER.fetch_add(1, Ordering::Relaxed);
}

fn main() {
    println!("{}", GREETING);
    println!("MAX = {}", MAX);

    increment();
    increment();
    increment();
    println!("COUNTER = {}", COUNTER.load(Ordering::Relaxed));
}

Recap

  • A static has a fixed memory address; one copy is shared by the whole program.
  • A const has no fixed address; its value is embedded at use sites — use const most of the time.
  • static mut requires unsafe for both reads and writes and should almost never be used.
  • Alternatives: AtomicXxx, Mutex<T>, LazyLock.