Rustlings Topic: Variables

In Rust, variables are immutable by default. When a variable is immutable, once a value is bound to a name, you can’t change that value. You can make them mutable by adding mut in front of the variable name.

This is the first topic of the rustlings. And there is nothing really special about it.
Exercises are just checking whether you are familiar with the basic syntaxes of the Rust.
If you find any of the exercises a bit confusing, please re-read The Book and/or Rust By Example.

You may find solution code for the topic from my repo.

  1. variables1.rs
  2. variables2.rs
  3. variables3.rs
  4. variables4.rs
  5. variables5.rs
  6. variables6.rs

variables1.rs

Rust uses let keyword to create a new variable binding.

/* file: "exercises/variables/variables1.rs" */
fn main() {
    let x = 5;
    println!("x has the value {}", x);
}

variables2.rs

If we only declared variables without type annotation or initialize value, the compiler has no idea what that variable type will be.

So, it will return error like below:

error[E0282]: type annotations needed
 --> exercises/variables/variables2.rs:5:9
  |
5 |     let x;
  |         ^ consider giving `x` a type

error: aborting due to previous error

What if we give a type annotation like let x: u32;?
That should surely fix above error right?
Tne answer is ‘yes it does’…
But we will encounter another error:

error[E0381]: use of possibly-uninitialized variable: `x`
 --> exercises/variables/variables2.rs:6:8
  |
6 |     if x == 10 {
  |        ^ use of possibly-uninitialized `x`

error: aborting due to previous error

The error says we are trying to use the declared variable without initializing it.

So the proper answer would be either

  1. Give x initialize value (type will be deduced by the compiler)
  2. Give x initialize value AND type annotation.
/* file: "exercises/variables/variables2.rs" */
fn main() {
    let x: u32 = 10;
    if x == 10 {
        println!("Ten!");
    } else {
        println!("Not ten!");
    }
}

variables3.rs

In Rust, variable bindings are immutable by default.
But here we’re trying to reassign a different value to x!

We can add mut to the variable binding to inform the compiler that we want to modify the variable in later use.

/* file: "exercises/variables/variables3.rs" */
fn main() {
    let mut x = 3;
    println!("Number {}", x);
    x = 5; // don't change this line
    println!("Number {}", x);
}

variables4.rs

I have already explained that we must initialize a variable before use in variables2.
If not, we will encounter an error like the below:

error[E0381]: borrow of possibly-uninitialized variable: `x`
 --> exercises/variables/variables4.rs:6:27
  |
6 |     println!("Number {}", x);
  |                           ^ use of possibly-uninitialized `x`

error: aborting due to previous error

Initialize the variable x.

/* file: "exercises/variables/variables4.rs" */
fn main() {
    let x: i32 = 1;
    println!("Number {}", x);
}

variables5.rs

Sometimes we may also like to reuse existing variable names because we are just converting values to different types like in this exercise.
Fortunately, Rust has a powerful solution to this problem: ‘Shadowing’!
you can read more about ‘Shadowing’ in the book’s section Variables and Mutability.

/* file: "exercises/variables/variables5.rs" */
fn main() {
    let number = "T-H-R-E-E"; // don't change this line
    println!("Spell a Number : {}", number);
    let number = 3;
    println!("Number plus two is : {}", number + 2);
}

variables6.rs

Constants are always immutable and they are declared with the keyword const rather than the keyword let. Constants types must also always be annotated.

/* file: "exercises/variables/variables6.rs" */
const NUMBER:i32 = 3;
fn main() {
    println!("Number {}", NUMBER);
}

Continue with Rustlings Solution