Rust by Example: Constants and Statics
Learn the difference between 'const' and 'static' for defining global values. This example explains when to use inlined constants versus fixed-address static variables and the implications for memory and safety.
Code
// Constants: Inlined at compile time
// Must have explicit type annotation
const MAX_POINTS: u32 = 100_000;
// Statics: Fixed memory location
// 'static lifetime is inferred
static HELLO_WORLD: &str = "Hello, world!";
// Mutable Statics (Unsafe!)
static mut COUNTER: u32 = 0;
fn main() {
println!("Max points: {}", MAX_POINTS);
println!("Static string: {}", HELLO_WORLD);
// Accessing mutable statics requires unsafe block
unsafe {
COUNTER += 1;
println!("Counter: {}", COUNTER);
}
// Constants can be defined inside functions too
const PI: f64 = 3.14;
println!("Pi is approx {}", PI);
}Explanation
Rust provides two keywords for defining global values: const and static. They differ fundamentally in memory layout.
const declares a value that is inlined at compile time. It has no fixed memory address. Wherever you use the constant, the compiler effectively copy-pastes the literal value. This is preferred for simple values like magic numbers or configuration limits because it allows for aggressive optimization.
static declares a variable with a fixed memory address in the program's data segment. Every reference to a static refers to the same data. While statics can be mutable (static mut), accessing them is unsafe.
- Data Races: Without synchronization, multiple threads could write to the static simultaneously.
- Aliasing: You can create multiple mutable references (
&mut) to the same static, violating Rust's core borrowing rules.
std::sync::Mutex, RwLock, or Atomic types.
Code Breakdown
const MAX_POINTS: u32. Constants MUST have a type annotation. The naming convention is SCREAMING_SNAKE_CASE.static HELLO_WORLD. This string is stored in the static memory segment of the binary. It lives for the entire duration of the program ('static lifetime).unsafe { ... }. Because multiple threads could theoretically write to COUNTER at the same time, Rust forces you to acknowledge the risk by wrapping the access in an unsafe block.
