Rust - Constant
Rust - Constants
Section titled “Rust - Constants”A constant is a value that is bound to a name and is not allowed to change. In Rust, constants are declared using the const keyword and their type must always be annotated.
const MAX_POINTS: u32 = 100_000;Naming Convention and Scope
Section titled “Naming Convention and Scope”The naming convention for constants is to use all uppercase letters with underscores between words (SCREAMING_SNAKE_CASE). Constants can be declared in any scope, including the global scope, making them useful for values that are shared across many parts of a program.
const SECONDS_IN_MINUTE: u32 = 60;const MINUTES_IN_HOUR: u32 = 60;const SECONDS_IN_HOUR: u32 = SECONDS_IN_MINUTE * MINUTES_IN_HOUR;
fn main() { println!("There are {} seconds in an hour.", SECONDS_IN_HOUR);}Output
Section titled “Output”There are 3600 seconds in an hour.Differences Between const and Immutable let
Section titled “Differences Between const and Immutable let”You might wonder why we need constants when Rust has immutable variables by default (let). While they seem similar, there are important differences:
- Type Annotation: You must annotate the type of a
const. Withlet, type annotation is usually optional as the compiler can infer it. - Mutability:
constvalues can never be made mutable withmut. Whileletbindings are immutable by default, they can be marked withmut. - Evaluation Time: A
constmust be set to a constant expression, a value that the compiler can determine at compile time. It cannot be the result of a function call or any value computed at runtime. - Inlining:
constvalues are effectively inlined into the code wherever they are used. This means there is no single memory address for aconst. - Scope:
constcan be declared in any scope, including globally.letis limited to function or block scope.
Code Example: Compile-time vs. Runtime
Section titled “Code Example: Compile-time vs. Runtime”fn get_runtime_value() -> u32 { // Some complex calculation... 5}
fn main() { // This is valid: The value is computed at compile time. const COMPILE_TIME_VALUE: u32 = 5 * 2;
// This is NOT valid: The value is computed at runtime. // const RUNTIME_VALUE: u32 = get_runtime_value(); // Error: calls in constants are limited to constant functions
// An immutable variable is fine for runtime values. let runtime_variable = get_runtime_value();
println!("Compile-time: {}, Runtime: {}", COMPILE_TIME_VALUE, runtime_variable);}A Note on static
Section titled “A Note on static”Rust has another way to create a value that lives for the entire duration of the program: a static variable. Unlike const, a static variable has a fixed memory location. static variables can also be mutable (using static mut), but accessing or modifying a mutable static variable is unsafe because it can introduce data races. For values that never change, const is almost always the better choice.
static HELLO_WORLD: &str = "Hello, world!";
fn main() { println!("Static says: {}", HELLO_WORLD);}Shadowing of Constants is Not Allowed
Section titled “Shadowing of Constants is Not Allowed”Unlike variables declared with let, constants cannot be shadowed. Attempting to declare another constant with the same name in the same scope will result in a compile-time error.
fn main() { const NAME: &str = "Alice"; // The following line will cause a compiler error: // const NAME: usize = 0; // error[E0260]: the name `NAME` is defined multiple times
println!("Name is {}", NAME);}