Variables

Rust’s approach to variables is straight-forward, but strict in a way that requires clear understanding.

(Im)Mutability

Rust variables are immutable by default. This difference from other languages is relatively easy to comprehend. .NET developers are accustomed to the immutability of string, for example, so transitioning to Rust’s mutability model is pretty easy.

Variable mutability is declarative in Rust, a bit like accessibility in .NET. Developers use mut keyword to declare a variable to be mutable.

let x = 66;
let mut y = 7400;
y = x + y;  // y now contains 7466
x = x + y;  // error[E0384]: cannot assign twice to immutable variable `x`

Strict Data Types

Compiled Rust code is much more secure than alternative languages, partly due to being strict about data types. How many bytes does a C# long occupy? Can an Int32 be assigned to a long without casting? Ok, maybe these questions are a bit easy, but the point is that Rust is very strict with regard to data types and memory layout.

Each Rust variable is a specific type, and the language does not offer implicit casting.

let x: i16 = 66;
let mut y: i32 = 7400;
let sum: i32 = y + x;

The Rust compiler will not allow this simple cast (16-bit integer into 32-bit), giving

error[E0308]: mismatched types
 --> src/main.rs:5:24
  |
5 |     let sum: i32 = y + x;
  |                        ^ expected `i32`, found `i16`

Fortunately, Rust’s errors are typically specific on the cause of the error. In this case, the error information clearly indicates that x has the wrong type.

Null Not Allowed!

Yep, you read that correctly – Rust does not support null. How in the world can we write code without relying on null? As the Rust book explains, null has historically been used to indicate that a variable held no value, and gives the rationale for Option<T> (which relies on Rust’s rich enum capabilities) to provide an idiomatic replacement for null.

enum Option<T> {
    Some(T),
    None,
}

Which leads to code similar to null checking

let x: Option<i16> = None;

if x != None {
    println!("x has a value");
} else {
    println!("x has NO value");
}

Although this approach leads Rust code to be more verbose, it is hard to overstate the huge stability benefit – no more null related bugs such as accidentally dereferencing null!

Leave a Reply