Rust is a fast, reliable, and memory-safe programming language that’s gaining widespread adoption for systems programming, web development, embedded systems, and beyond. In this beginner’s guide, we’ll introduce the fundamentals of Rust and walk through simple examples to help you write your first Rust program with confidence.
Why Learn Rust?
Rust stands out for its unique combination of performance and safety. It compiles to native code, offers zero-cost abstractions, and enforces memory safety without a garbage collector. Here’s why developers love Rust:
-
Memory Safety: Prevents null pointer dereferencing and data races.
-
Speed: As fast as C and C++.
-
Concurrency: Built-in support for multithreading.
-
Developer Tools: Great compiler error messages and an excellent package manager (
cargo
). -
Growing Ecosystem: Used by companies like Mozilla, Dropbox, Amazon, and Microsoft.
Setting Up the Rust Environment
To start coding in Rust, first install the official toolchain:
Step 1: Install Rust
Run the following command in your terminal:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
After installation, restart your terminal and verify:
rustc --version
cargo --version
Step 2: Create a New Rust Project
cargo new hello_rust
cd hello_rust
This generates a basic Rust project with a main.rs
file inside src/
.
Your First Rust Program
Let’s explore a simple “Hello, World!” program:
fn main() {
println!("Hello, Rust!");
}
To run it:
cargo run
Breakdown
-
fn main()
is the entry point. -
println!
is a macro for printing text to the console. -
Semicolons
;
end statements in Rust.
Understanding Rust Variables
Rust variables are immutable by default. Use mut
to make them mutable.
fn main() {
let x = 5;
println!("x is {}", x);
let mut y = 10;
println!("y is {}", y);
y = 20;
println!("now y is {}", y);
}
Data Types in Rust
Rust is statically typed. Common types include:
-
Integers:
i32
,u64
, etc. -
Floats:
f32
,f64
-
Boolean:
bool
-
Character:
char
-
Tuple and Array
Example:
fn main() {
let tup: (i32, f64, char) = (1, 3.14, 'R');
let arr = [1, 2, 3, 4, 5];
println!("First tuple item: {}", tup.0);
println!("Array length: {}", arr.len());
}
Control Flow in Rust
Rust supports if
, else
, match
, loop
, while
, and for
.
if
and else
fn main() {
let number = 7;
if number < 10 {
println!("Less than 10");
} else {
println!("10 or more");
}
}
match
Statement
fn main() {
let num = 2;
match num {
1 => println!("One"),
2 => println!("Two"),
_ => println!("Something else"),
}
}
Functions in Rust
Functions are declared using fn
:
fn greet(name: &str) {
println!("Hello, {}!", name);
}
fn main() {
greet("Rust");
}
Functions can return values:
fn add(x: i32, y: i32) -> i32 {
x + y
}
Ownership and Borrowing
Rust’s most unique feature is its ownership model, which helps manage memory safely.
Ownership Example
fn main() {
let s1 = String::from("hello");
let s2 = s1; // ownership moved
// println!("{}", s1); // error: s1 no longer valid
}
Error Handling
Rust uses Result
and Option
types instead of exceptions.
use std::fs::File;
fn main() {
let file = File::open("hello.txt");
match file {
Ok(f) => println!("File opened successfully"),
Err(e) => println!("Error: {}", e),
}
}
Advanced Rust Concepts (For the Curious Beginner)
Once you're comfortable with the basics, Rust offers more powerful abstractions that are both safe and efficient.
Structs and Enums
Structs
Structs let you define custom types:
struct User {
username: String,
age: u8,
}
fn main() {
let user1 = User {
username: String::from("djamware"),
age: 30,
};
println!("Username: {}", user1.username);
}
Enums
Enums are perfect for types that can be one of several variants:
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
}
fn main() {
let msg = Message::Write(String::from("Hello"));
match msg {
Message::Quit => println!("Quit"),
Message::Move { x, y } => println!("Move to ({}, {})", x, y),
Message::Write(text) => println!("Text: {}", text),
}
}
Traits and Generics
Rust doesn’t have traditional OOP classes, but you can achieve polymorphism with traits.
trait Greet {
fn greet(&self);
}
struct Person;
struct Robot;
impl Greet for Person {
fn greet(&self) {
println!("Hi! I'm a person.");
}
}
impl Greet for Robot {
fn greet(&self) {
println!("Beep boop. I'm a robot.");
}
}
fn say_hello<T: Greet>(greeter: T) {
greeter.greet();
}
Lifetimes (Introduction)
Lifetimes ensure references are valid. Here’s a simple example:
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
This function returns a reference that’s valid as long as both inputs are.
Build a Simple CLI Project in Rust
Let’s use your new skills to build a command-line to-do list app using Rust.
Step 1: Create a New Project
cargo new todo_cli
cd todo_cli
Step 2: Update Cargo.toml
Add dependencies:
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
Step 3: Basic Task Struct
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
pub struct Task {
pub(crate) title: String,
pub(crate) done: bool,
}
Step 4: Add Functionality
Create, list, and toggle tasks.
use serde::{ Serialize, Deserialize };
use std::fs::{ OpenOptions };
use std::io::{ Read, Write };
#[derive(Serialize, Deserialize)]
pub struct Task {
pub(crate) title: String,
pub(crate) done: bool,
}
pub fn load_tasks() -> Vec<Task> {
let mut file = OpenOptions::new()
.read(true)
.create(true)
.open("tasks.json")
.expect("Failed to open file");
let mut content = String::new();
file.read_to_string(&mut content).unwrap();
if content.is_empty() {
return vec![];
}
serde_json::from_str(&content).unwrap()
}
pub fn save_tasks(tasks: &[Task]) {
let json = serde_json::to_string_pretty(tasks).unwrap();
let mut file = OpenOptions::new().write(true).truncate(true).open("tasks.json").unwrap();
file.write_all(json.as_bytes()).unwrap();
}
Step 5: Main CLI Logic
mod task;
use task::{ Task, load_tasks, save_tasks };
fn main() {
let args: Vec<String> = std::env::args().collect();
let mut tasks = load_tasks();
match args.get(1).map(|s| s.as_str()) {
Some("add") => {
let title = args.get(2).expect("No task title provided");
tasks.push(Task {
title: title.clone(),
done: false,
});
save_tasks(&tasks);
println!("Task added.");
}
Some("list") => {
for (i, task) in tasks.iter().enumerate() {
let status = if task.done { "✓" } else { " " };
println!("[{}] {}: {}", status, i, task.title);
}
}
Some("done") => {
let index: usize = args.get(2).unwrap().parse().unwrap();
if let Some(task) = tasks.get_mut(index) {
task.done = true;
save_tasks(&tasks);
println!("Task marked as done.");
}
}
_ => {
println!("Usage: todo_cli [add|list|done] [task]");
}
}
}
Step 6: Run It
cargo run -- add "Learn Rust"
cargo run -- list
cargo run -- done 0
What’s Next?
You’ve now:
-
Written your first Rust programs
-
Learned core concepts: variables, ownership, functions, structs, enums
-
Built a basic CLI app using external crates
Conclusion
Rust may have a steep learning curve at first, but its powerful features and safety guarantees make it well worth the effort. In this beginner’s guide, you’ve explored the core concepts of Rust—from variables, control flow, and functions to ownership, structs, and enums. You’ve also taken your first steps toward building real-world applications by creating a simple command-line to-do app.
What sets Rust apart is its focus on memory safety without a garbage collector, and its ability to catch many bugs at compile time. These qualities make it a top choice for systems programming, high-performance applications, and even web backends.
Whether you're coming from JavaScript, Python, or C++, learning Rust can sharpen your skills and change the way you think about programming.
You're now equipped to:
-
Understand the Rust syntax and core concepts
-
Write and run basic Rust programs
-
Start experimenting with real-world projects
Next up? Dive deeper into Rust's ecosystem—build a REST API, try async programming, or explore frontend frameworks like Yew. The Rust journey has just begun, and you're off to a strong start.
You can get the full source code of the Basic Rust and Todo CLI App.
That is just the basics. If you need more deep learning about the Rust language and frameworks, you can take the following cheap course:
- Rust for Beginners
- Build API Servers with Rust and Actix
- Rust Proficiency Test: Core Concepts Evaluation
- Build an AutoGPT Code Writing AI Tool With Rust and GPT-4
- Building Web Applications with Rust and WebAssembly
Thanks!