In Rust, there are two main ways to store immutable data throughout the execution of a program: const and static.
Constant (const) is an immutable value computed at compile time. It must always be explicitly typed and initialized with a constant expression (which can be computed at compile time). Constants do not have a fixed memory address and are "inlined" by the compiler at the places of use.
const MAX_ATTEMPTS: u32 = 5;
Static variable (static) stores a value in a specific memory area for the entire duration of the program. Its address is fixed, and it can be mutable (using static mut), but access to it requires special precautions due to potential data races in multithreaded scenarios.
static APP_NAME: &str = "MyApp"; static mut COUNTER: u32 = 0;
const when the value must always be known at compile-time and does not need global storage.static if a single place of storage in memory is required, which all modules can access, or if the value cannot be computed at compile time.What is the difference between
constandstaticin Rust? Can a static variable refer to a non-constant?
Answer: The main difference is the storage duration (lifetime): const does not guarantee the existence in memory (it's a value substitution), while static is an object that lives for the entire duration of the program with a fixed address.
A static variable can only be assigned a value that is known at compile time:
let a = 42; // static INVALID: i32 = a; // Error! Only constants are allowed.
History
In a backend service project for load distribution, one of the developers used static mut for a shared request counter from different threads without using synchronization. This led to data races and unpredictable results — some requests were simply lost. The solution is to use atomic types from std::sync::atomic, or Mutex.
History
A young developer decided to extract the user greeting string into a constant using const, but tried to link it to the result of a function computed during initialization. The compiler raised an error because the value must be defined at compile time. The reason is that a constant must be computable at compile time, while a function returns a value at runtime.
History
In an old project, all global values were replaced with static, forgetting that string literals with references use the program's memory area, while some declarations actually required only value substitution: this increased the binary size and complicated memory management. The result was increased startup time and leaks when dynamically loading libraries.