A practical starting point for Rust: create a Cargo project, run it, and learn variables, mutability, constants, scope, and shadowing before moving to types and ownership.
A practical starting point for Rust: create a Cargo project, run it, and learn variables, mutability, constants, scope, and shadowing before moving to types and ownership.
Rust is a statically typed systems programming language with an ownership model that checks memory use at compile time. This introduction starts with a Cargo project, then covers variables, mutability, constants, scope, and shadowing. It is the starting point for the Rust Fundamentals series.
Rust gives you control over data layout and resource lifetimes while checking many memory-safety rules during compilation. That control comes with a learning cost: the compiler asks you to make ownership and borrowing decisions explicit.
The goal is to build reliable systems without requiring a tracing garbage collector. Safe Rust rules out several classes of invalid memory access, but it does not eliminate logic bugs or guarantee that a program is fast.
Rust began as Graydon Hoare’s personal project in 2006, with Mozilla involvement beginning in late 2009. Rust 1.0 was released on 15 May 2015.
Cargo is Rust’s package manager and build system. It simplifies compiling, testing, and running Rust projects. Cargo also serves as a test runner, documentation generator, and dependency manager.
To start a new Rust project, you can use Cargo:
cargo new helloBashThis creates a directory structure like this:
hello
├── Cargo.toml
└── src
└── main.rsBashThe Cargo.toml file holds the project’s metadata, including its dependencies, while src/main.rs is where the main Rust code resides.
fn main() {
println!("Hello, world!");
}RustRunning the project is as simple as:
cargo runBashVariables in Rust are immutable by default. This immutability ensures that once a value is assigned, it cannot be altered, contributing to Rust’s emphasis on safety and performance.
let x = 5;
x = 6; // This will result in a compile-time error.RustTo make a variable mutable, you can use the mut keyword:
let mut x = 5;
x = 6; // This is allowed.RustRust also supports constants, which are always immutable and must be defined with explicit type annotations.
const MAX_POINTS: u32 = 100_000;RustConstants can be used wherever they are in scope. Their values are evaluated at compile time; that is a language rule, not a promise that using a constant makes an operation faster.
The scope of a variable in Rust determines where it is valid within the program. Rust also allows variable shadowing, where a new variable with the same name can be declared within the same scope, effectively replacing the previous one.
let x = 5;
{
let x = 10;
println!("{}", x); // Outputs 10
}
println!("{}", x); // Outputs 5RustShadowing can even change the variable’s type:
let x = "hello";
let x = x.len(); // `x` is now a number.RustThis feature is particularly useful in scenarios like data conversion and transformation.
One of Rust’s standout features is its guarantee of memory safety at compile time. Variables in Rust must be initialized before use, and the compiler enforces this rule strictly.
let x: i32;
println!("{}", x); // This will result in a compile-time error.RustRust’s compiler ensures that all variables are initialized before they are used, preventing common bugs and vulnerabilities that plague other systems programming languages.
You now have the basic workflow for creating and running a Rust program. Next, learn Rust scalar types and function parameters and return values. Ownership and borrowing build on these foundations.

Senior Technical Architect at HCLTech · working with Leonteq Security AG
I have 10+ years of experience building distributed systems and fintech platforms. I write about practical, non-obvious engineering details that official documentation often skips.
Scala, JVM, AI, and backend systems. I send practical articles when there is something worth reading.
Join the newsletter