Chapter 9: Rust Constants
Rust Constants. This is a perfect follow-up because constants are like the “super-immutable” cousins of the let variables we talked about last time.
In Rust, constants are not the same as just making a variable immutable with let. They have special rules, special powers, and special use cases. Let me explain everything slowly and clearly, like we’re sitting together in a café near Gachibowli, with code examples you can run right now, comparisons to everyday things, and tables to make it crystal clear.
1. What Are Constants in Rust? (The Big Picture)
Constants are values that are:
- Known completely at compile time (the compiler calculates them before your program even runs)
- Impossible to change — ever — during the entire life of your program
- Usually written in ALL_CAPS_WITH_UNDERSCORES (convention, like in many languages)
- Used for fixed, unchanging values like math constants, configuration limits, magic numbers, API keys (in safe way), etc.
Rust actually has two kinds of “constants”:
- const → the normal, most common one (this is what people usually mean by “Rust constants”)
- static → a special global constant (or mutable global in unsafe code) with a fixed memory address
Today we’ll focus mostly on const (90% of cases), and I’ll explain static at the end so you don’t get confused.
2. Declaring a const — Syntax & Rules
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
// Must write the TYPE explicitly (no inference!) const MAX_USERS: u32 = 100_000; // Can use underscores for readability const PI: f64 = 3.141_592_653_589_793; // Can be expressions — evaluated at compile time const SECONDS_IN_A_DAY: u64 = 60 * 60 * 24; // Global scope (outside functions) is very common const HYDERABAD_AVG_TEMP_SUMMER: u32 = 38; fn main() { println!("Max users allowed: {}", MAX_USERS); println!("Seconds in a day: {}", SECONDS_IN_A_DAY); } |
Key rules you must follow (compiler will error otherwise):
- Type annotation required — no let-style inference
- Value must be computable at compile time — only simple math, no function calls (unless const fn), no runtime I/O, no Vec::new()
- Always immutable — no mut allowed (compiler error if you try)
- Cannot be shadowed — you can’t redeclare const MAX_USERS later
- Naming convention: SCREAMING_SNAKE_CASE (all uppercase + underscores)
3. const vs Immutable let — Why Two Things?
This is where beginners get confused — here’s the clear comparison (2026 style):
| Feature | let (immutable) | const |
|---|---|---|
| Keyword | let | const |
| Type annotation | Optional (inferred) | Required |
| Value computed when? | At runtime (when code executes) | At compile time |
| Can change value? | No (unless shadowed) | Never — impossible |
| Can shadow? | Yes (redeclare same name) | No |
| Can be mutable? | Yes — add mut | No — forbidden |
| Memory location | Normal variable (stack/heap) | Inlined wherever used (no single location) |
| Can use in array sizes? | No (needs const context) | Yes |
| Global scope? | Possible but rare | Very common & encouraged |
| Typical use | Normal program logic variables | Fixed limits, math constants, configs |
Example showing difference:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
fn main() { // Immutable let — computed at runtime let today_temp = 32 + 3; // happens when main runs // const — computed by compiler before program exists const MAX_TEMP: i32 = 45; // today_temp = 40; // ERROR if no mut // const MAX_TEMP = 50; // ERROR — can't redeclare const } |
4. Real-Life Examples You Can Run
Create a quick project:
|
0 1 2 3 4 5 6 7 |
cargo new rust_constants cd rust_constants |
Put this in src/main.rs:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
// Global constants — common style const GRAVITY_MS2: f64 = 9.80665; const MAX_PASSWORD_LENGTH: usize = 128; const TELUGU_GREETING: &str = "Namaste Hyderabad!"; const DAYS_IN_WEEK: u8 = 7; const HOURS_IN_DAY: u8 = 24; const MINUTES_IN_HOUR: u8 = 60; // Computed at compile time const MINUTES_IN_WEEK: u32 = MINUTES_IN_HOUR as u32 * HOURS_IN_DAY as u32 * DAYS_IN_WEEK as u32; fn main() { println!("Gravity constant: {} m/s²", GRAVITY_MS2); println!("Minutes in a week: {} (calculated at compile time!)", MINUTES_IN_WEEK); println!("Greeting: {}", TELUGU_GREETING); // You can use const in array sizes! let weekdays: [&str; DAYS_IN_WEEK as usize] = [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" ]; println!("First weekday: {}", weekdays[0]); } |
Run cargo run — see how everything is baked in at compile time.
5. Advanced but Useful: const in Array Lengths & Generics
|
0 1 2 3 4 5 6 7 8 |
const BUFFER_SIZE: usize = 1024; let buffer: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE]; // OK — const usize needed! |
This is impossible with normal let (even immutable) because array size must be known at compile time.
6. Quick Note on static (The Other “Constant”)
static is like const but:
- Has a fixed memory address (single instance in the program)
- Has ‘static lifetime
- Can be mutable (but only in unsafe code — dangerous!)
- Used for global state, FFI, singletons, etc.
|
0 1 2 3 4 5 6 7 8 9 10 11 |
static APP_NAME: &str = "My Rust App"; // immutable static static mut COUNTER: u32 = 0; // mutable — requires unsafe! fn main() { println!("App: {}", APP_NAME); } |
Rule of thumb in 2026: Use const for 95% of cases. Use static only when you need a fixed address (rare for beginners).
Teacher Summary
Rust Constants (const) = values that are:
- Fixed forever
- Computed at compile time
- Typed explicitly
- Inlined (no single memory spot)
- Perfect for magic numbers, limits, math constants, configs
They are stronger than immutable let — more like “this value is part of the program’s DNA, it never changes.”
Practice: Go add 5–10 constants to your existing projects (max score, pi value, pin codes, etc.). Try using them in array sizes or calculations — feel how clean it is!
Next topic ready?
- static in more detail?
- Strings (&str vs String — constants love &str)?
- Or ownership with constants/variables?
Just say — your Hyderabad Rust teacher is right here! 🦀🚀
