Immutable vs const in Rust: What's the Difference? Guide 2025

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Immutable vs const in Rust: Why Even Experienced Developers Get Confused?

\n\n

Have you ever written code in Rust and suddenly thought: "Wait, I declared a variable with let, it's immutable. And const is also kind of a constant. So what's the difference?". If so — you are not alone. The question "What is the difference between immutable and const variables in Rust?" on Stack Overflow has thousands of views. And this is no coincidence.

\n\n

At first glance, it seems that both let x = 5 and const X: i32 = 5 do the same thing: they prevent changing the value. But in Rust, a language where memory safety and performance are paramount, the devil is in the details. In 2025, understanding these details is not just theory, but a necessity for writing efficient and idiomatic code.

\n\n

In this article, we will once and for all figure out: how is an immutable variable different from a constant, when to use what, and what best practices are relevant right now. Let's go!

\n\n

1. Basic Understanding: What Does the Compiler Say?

\n\n

Let's start with the simplest. In Rust, variables are immutable by default. This means that after assigning a value, you cannot overwrite it.

\n\n
fn main() {\n    let x = 5;\n    // x = 6; // Error! Cannot change an immutable variable\n    println!("x = {}", x);\n}
\n\n

And here's an example with a constant:

\n\n
const MAX_POINTS: u32 = 100_000;\n\nfn main() {\n    println!("MAX_POINTS = {}", MAX_POINTS);\n}
\n\n

Visually — it looks similar. But the Rust compiler handles them completely differently. And this is where the interesting part begins.

\n\n

1.1. Key Difference #1: Where Do They Live?

\n\n
    \n
  • let — declares a variable. It exists on the stack (or heap, if it's a Box, String, etc.) and has a memory address. You can take a reference to it, pass it to functions, move it.
  • \n
  • const — declares a constant. It does not have a fixed memory address. The compiler inlines its value directly into the code at the point of use.
  • \n
\n\n

This is a fundamental difference. const is not a variable; it's a named value that is substituted at compile time.

\n\n
fn main() {\n    let x = 42;\n    let y = &x; // Ok, taking a reference to a variable\n\n    const Z: i32 = 100;\n    // let w = &Z; // Error! A constant has no address, cannot take a reference\n}
\n\n

2. Deep Dive: Performance and Semantics

\n\n

Now that we know about the "place of residence", let's break down other important aspects.

\n\n

2.1. Lifetime and Scope

\n

Constants live in the global scope (or inside a function, but with a static lifetime). They exist for the entire duration of the program. They can be declared outside a function and will be accessible everywhere.

\n\n

Immutable variables only live inside a block (function, loop, if). Once the block ends, the memory is freed.

\n\n
const GLOBAL_CONST: i32 = 10;\n\nfn main() {\n    let local_var = 20;\n    // local_var only lives inside main\n}\n// local_var no longer exists\n// GLOBAL_CONST is still accessible
\n\n

2.2. Type and Annotations

\n

For const, specifying the data type is mandatory. For let, the compiler will infer it.

\n\n
const PI: f64 = 3.14159; // Mandatory: const NAME: Type = value;\nlet pi = 3.14159; // The compiler will figure out it's f64
\n\n

2.3. Compile-Time Evaluation (CTFE)

\n

The value of const must be computable at compile time.

Blogs

Book Recommendations