Understanding Variables and Mutability in Rust

Hi everyone. Before that, I wrote a post called Getting Started with Rust.

Today’s topic is Variables and Mutability. We’ll see how they work in Rust.

Rust Programming Language

Introduction

Are the thoughts immutable or constant? Maybe they can be mutable.

Rust has many advantages and of course disadvantages like other programming languages. Rust allows you to write your code in safety and easy concurrency. This is the first good thing we have in Rust.

By default variables are immutable in Rust. But you still have an option to make them mutable. So, why we should use immutable variables? And when we should use mutable variables? These are some questions we’ll ask ourselves while learning Rust.

Don’t worry, we’ll try to find answers to all those questions with this post.

Creating a New Project

We’ll create a new project for this post called variables_and_mutability.

cargo new variables_and_mutability

cd variables_and_mutability

Immutable Variable

Immutable Variable

If you declare a variable it will be immutable by default. So, what does it mean?

src/main.rs

let age = 27;

println!("My age is {}", age);

Once you passed a value to a variable, you can’t change that value. You can’t do this;

let age = 27;

println!("My age is {}", age);

age = 26;

println!("No no my actual age is {}", age);

If you run this code, you’ll see an error like that;

error[E0384]: cannot assign twice to immutable variable `age`
 --> src/main.rs:7:5
  |
3 |     let age = 27;
  |         ---
  |         |
  |         first assignment to `age`
  |         help: make this binding mutable: `mut age`
...
7 |     age = 26;
  |     ^^^^^^^^ cannot assign twice to immutable variable

error: aborting due to previous error

For more information about this error, try `rustc --explain E0384`.

This is how compiler shows errors us. Don’t feel bad. Because Rust’s philosophy is different than others. This errors shows this message;

cannot assign twice to immutable variable

And it also shows how we can fix it

help: make this binding mutable: mut age

This is good because our program didn’t compile. You can still have immutable variables that will take values in runtime. Rust compiler guarantees that once you declare a variable won’t change, it won’t change.

Thanks to this feature, you don’t have to track always variable state change. Because you didn’t design it like that

Mutable Variable

Mutable Variable

Sometimes, we need mutable variables. For example we can have a code piece like that;

let is_fiscal_day: bool = false;

if some_control {
  is_fiscal_day = true;
}

We got an error in the Immutable Variable section. How we can fix it? Let’s see;

let mut age = 27;
/*  ^^^   */ 
println!("My age is {}", age);

age = 26;

println!("No no my actual age is {}", age);

We added mut keyword when we declared variable. There are trade-offs about mutable and immutable variables. Sometimes the mutating variable is faster than copying and returning instances. Sometimes, immutable variables can make your programs faster, etc.

Immutable Variables and Constants

Constant Variable

Immutable variables are very similar to constants. In both scenarios, immutable and constant variables can’t be changed once they declared. But there are a few differences between them.

Firstly, you can’t use the mut keyword with constant variables. immutable variables by default immutable. But they can be mutable. Constants are always immutable. Their state can’t be changed.

We use const keyword for constants

const IS_VIP: bool = true;

println!("Is VIP user: {}", IS_VIP);

You have to specify the type for constants. Variables declared with let keyword will know their data type by value data type unless you specify a data type. For example;

let name = "Ali"; // ----> type: string

let age = 27; // ---> type: integer

let pi = 3.14; // ---> type: float

However, constants have to know their data type. You can’t declare a constant variable without a data type.

const IS_VIP = true;

The compiler will show an error us;

error: missing type for `const` item
  --> src/main.rs:11:11
   |
11 |     const IS_VIP = true;
   |           ^^^^^^ help: provide a type for the item: `IS_VIP: bool`

Shadowing

Shadowing

It’s was the hardest part to understand for me in Rust. By this approach, you can declare a new variable with the same name as a previous variable. From this moment, new variable shadows the previous variable. Experienced Rust programmers say that the first variable is shadowed by the second variable. We can say that the second value is what appears when the variable is used.

We can shadow variables using let keyword.

fn main() {
  let age = 26;

  let age = age + 1;

  println!("My age is: {}", age);
}

When you run this code, you will see the following outputs;

Compiling playground v0.0.1 (/variables_and_mutability)
    Finished dev [unoptimized + debuginfo] target(s) in 0.66s
     Running `target/debug/variables_and_mutability`
My age is: 27

Shadowing and Mutability

Shadowing and mutability are different things in Rust. You can shadow variables how much you want. The second thing you should know is when you try to reassign a shadowed variable without let keyword, you will get a compile-time error.

When you shadow a variable, you’ll create a new variable with the same name and its data-type can be changed than others.

let age = 27;
let age = "Ali";

Rust allows you to shadow variables in different data types. You can’t do the same thing without the shadowing variable. Let’s try

let mut name = "Ali";
name = name.len();

println!("My name is {}", name);

You will see the following errors;

Compiling playground v0.0.1 (/variables_and_mutability)
error[E0308]: mismatched types
 --> src/main.rs:4:11
  |
4 |     name = name.len();
  |           ^^^^^^^^^ expected `&str`, found `usize`

Now that we’ve explored how variables work and how mutability works in Rust, we’ll see the data types in the next chapter.

If there is any wrong information, please let me know.

Thanks for reading 🙂

Resources