2.6 Constants and Static Variables

Rust offers two ways to define values with fixed meaning or location:

2.6.1 Constants (const)

Constants represent values that are known at compile time. They must be annotated with a type and are typically defined in the global scope, though they can also be defined within functions. Constants are effectively inlined wherever they are used and do not have a fixed memory address. The naming convention is SCREAMING_SNAKE_CASE.

const SECONDS_IN_MINUTE: u32 = 60;
const PI: f64 = 3.1415926535;

fn main() {
    println!("One minute has {} seconds.", SECONDS_IN_MINUTE);
    println!("Pi is approximately {}.", PI);
}

2.6.2 Static Variables (static)

Static variables represent values that have a fixed memory location ('static lifetime) throughout the program’s execution. They are initialized once, usually when the program starts. Like constants, they must have an explicit type annotation. The naming convention is also SCREAMING_SNAKE_CASE.

static APP_NAME: &str = "Rust Explorer"; // A static string literal

fn main() {
    println!("Welcome to {}!", APP_NAME);
}

Rust strongly discourages mutable static variables (static mut) because modifying global state without synchronization can easily lead to data races in concurrent code. Accessing or modifying static mut variables requires unsafe blocks.

2.6.3 Comparison with C

  • Rust’s const is similar in spirit to C’s #define for simple values but is type-checked and integrated into the language, avoiding preprocessor pitfalls. It’s also akin to highly optimized const variables in C.
  • Rust’s static is closer to C’s global or file-scope static variables regarding lifetime and memory location. However, Rust’s emphasis on safety around mutable statics is much stricter than C’s.