Today I discovered excellent resources for learning Rust systematically, from
beginner-friendly interactive tutorials to advanced concepts that highlight why
Rust is becoming the go-to systems programming language.
Interactive Rust Learning
Tour of Rust - Interactive Learning
Tour of Rust provides an interactive way to learn
Rust similar to Go’s famous tour. It covers almost the entire Rust Book content
through hands-on exercises:
Tour of Rust Coverage
- Basics: Variables, functions, control flow
- Ownership: Borrowing, references, lifetimes
- Types: Structs, enums, traits, generics
- Error Handling: Result types and error propagation
- Memory Management: Stack vs heap, smart pointers
- Concurrency: Threads, channels, async/await
- Advanced Features: Macros, unsafe code, FFI
The interactive format allows you to run Rust code directly in the browser,
making it perfect for learning without setting up a local development
environment.
Rust by Example
Rust by Example takes a
hands-on approach to learning Rust concepts:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| // Pattern matching with enums
enum WebEvent {
PageLoad,
PageUnload,
KeyPress(char),
Paste(String),
Click { x: i64, y: i64 },
}
fn inspect(event: WebEvent) {
match event {
WebEvent::PageLoad => println!("page loaded"),
WebEvent::PageUnload => println!("page unloaded"),
WebEvent::KeyPress(c) => println!("pressed '{}'", c),
WebEvent::Paste(s) => println!("pasted \"{}\"", s),
WebEvent::Click { x, y } => {
println!("clicked at x={}, y={}", x, y);
},
}
}
fn main() {
let pressed = WebEvent::KeyPress('x');
let pasted = WebEvent::Paste("my text".to_owned());
let click = WebEvent::Click { x: 20, y: 80 };
inspect(pressed);
inspect(pasted);
inspect(click);
}
|
Advanced Rust Resources
Learn Rust the Dangerous Way
Learn Rust the Dangerous Way by Cliff Biffle
teaches Rust from the perspective of a C programmer, highlighting dangerous
practices and how Rust prevents them:
Common Dangerous Patterns
C/C++ Problems that Rust
Solves:
- Buffer overflows - Rust’s bounds checking prevents array access violations
- Use-after-free - Ownership system ensures memory safety
- Double-free - RAII and ownership prevent double deallocations
- Data races - Type system enforces thread safety at compile time
- Null pointer dereferences - Option types eliminate null pointer errors
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| // Rust prevents dangerous memory access
fn safe_array_access() {
let arr = [1, 2, 3, 4, 5];
// This would panic at runtime, not cause undefined behavior
// let value = arr[10]; // panic: index out of bounds
// Safe alternative using get()
match arr.get(10) {
Some(value) => println!("Value: {}", value),
None => println!("Index out of bounds"),
}
}
// Ownership prevents use-after-free
fn ownership_safety() {
let data = String::from("Hello");
let reference = &data;
// drop(data); // This would cause compile error
// println!("{}", reference); // Can't use reference after data is dropped
println!("{}", reference); // Safe because data is still alive
}
|
Little Book of Rust Macros
Little Book of Rust Macros
provides comprehensive coverage of Rust’s macro system:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| // Declarative macros (macro_rules!)
macro_rules! vec {
( $( $x:expr ),* ) => {
{
let mut temp_vec = Vec::new();
$(
temp_vec.push($x);
)*
temp_vec
}
};
}
// Usage
let v = vec![1, 2, 3, 4, 5];
// Custom debug macro
macro_rules! debug_print {
($($arg:tt)*) => {
#[cfg(debug_assertions)]
println!("[DEBUG] {}", format_args!($($arg)*));
};
}
// Only prints in debug builds
debug_print!("Processing item: {}", item_id);
|
Rust Adoption Challenges
Problems in Rust Adoption
discusses real-world challenges when adopting Rust:
Rust Adoption Considerations
Learning Curve Challenges:
- Ownership system - Requires fundamental shift in thinking
- Lifetime annotations - Complex for beginners coming from GC languages
- Compiler strictness - Initially frustrating but prevents runtime errors
- Ecosystem maturity - Some libraries still emerging compared to C++ or
Python
Migration Strategies:
- Start with new components rather than rewriting existing code
- Use Rust for performance-critical or safety-critical parts
- Leverage FFI to integrate with existing C/C++ codebases
- Invest in team training and mentorship
Py-Spy for Python Profiling
Py-Spy is a sampling profiler for Python
programs, written in Rust for minimal overhead:
1
2
3
4
5
6
7
8
9
10
11
| # Install py-spy
pip install py-spy
# Profile a running Python process
py-spy record -o profile.svg --pid 12345
# Profile a Python script
py-spy record -o profile.svg -- python myscript.py
# Top-like interface for live profiling
py-spy top --pid 12345
|
Why Py-Spy is Special
Unlike traditional Python profilers,
py-spy:
- Zero overhead when not profiling
- Works with any Python program without modification
- Minimal impact on the target process (written in Rust)
- Rich output formats including flame graphs and call trees
- Works with C extensions and shows full stack traces
The fact that py-spy is written in Rust demonstrates Rust’s effectiveness for
building high-performance tools that interact with other language runtimes.
Several excellent command-line tools are written in Rust, showcasing its
performance and ergonomics:
Tokei - Better Code Counting
tokei is a faster, more accurate
alternative to cloc:
1
2
3
4
5
6
7
8
9
10
11
| # Count lines of code in a project
tokei
# Specific languages only
tokei --languages rust,python
# Exclude test files
tokei --exclude '*.test.*'
# JSON output for automation
tokei --output json
|
Bat - Enhanced Cat
bat provides syntax highlighting and Git
integration:
1
2
3
4
5
6
7
8
| # View file with syntax highlighting
bat src/main.rs
# Show line numbers and git changes
bat --number --show-all src/main.rs
# Use as pager replacement
export PAGER="bat --plain"
|
Ripgrep - Superior Grep
ripgrep offers incredible search
performance:
1
2
3
4
5
6
7
8
9
10
11
| # Basic search
rg "pattern"
# Search specific file types
rg "TODO" --type rust
# Case insensitive with context
rg -i "error" -C 3
# Regular expressions
rg "fn\s+\w+\(" --type rust
|
Rust CLI Tool Benefits
These Rust-based tools
demonstrate key advantages:
- Performance: Significantly faster than traditional Unix tools
- Safety: Memory safety prevents crashes and undefined behavior
- Ergonomics: Better defaults and user-friendly output
- Cross-platform: Work consistently across Linux, macOS, and Windows
- Modern features: Git integration, syntax highlighting, smart defaults
Systems Programming Insights
Linux From Scratch
Linux From Scratch
teaches Linux system internals by building a complete Linux system from source
code:
The project helps understand:
- Boot process and system initialization
- Package management and dependency resolution
- System libraries and their interactions
- Kernel compilation and configuration
- Development toolchain creation
This knowledge is invaluable when working with Rust for systems programming, as
it provides deep understanding of the runtime environment where Rust programs
execute.
Memory Management Fundamentals
Understanding how Rust’s ownership system maps to actual memory management:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| // Stack allocation - automatic cleanup
fn stack_example() {
let x = 42; // Stored on stack
let y = [1, 2, 3]; // Array on stack
} // x and y automatically cleaned up
// Heap allocation - controlled by ownership
fn heap_example() {
let data = String::from("Hello"); // Heap allocated
let moved_data = data; // Ownership transfer
// println!("{}", data); // Compile error - data moved
println!("{}", moved_data); // OK - new owner
} // moved_data automatically freed
// Borrowing - temporary access without ownership transfer
fn borrowing_example() {
let data = String::from("World");
let len = calculate_length(&data); // Borrow, don't move
println!("Length of '{}' is {}", data, len); // data still valid
}
fn calculate_length(s: &String) -> usize {
s.len() // Can read, but can't modify without &mut
}
|
Integration and Interoperability
Foreign Function Interface (FFI)
Rust’s FFI capabilities make it excellent for:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| // Calling C code from Rust
extern "C" {
fn abs(input: i32) -> i32;
fn strlen(s: *const c_char) -> size_t;
}
// Exposing Rust code to C
#[no_mangle]
pub extern "C" fn add_numbers(a: i32, b: i32) -> i32 {
a + b
}
// Python extension using PyO3
use pyo3::prelude::*;
#[pyfunction]
fn fibonacci_rust(n: u64) -> u64 {
match n {
0 => 0,
1 => 1,
_ => fibonacci_rust(n - 1) + fibonacci_rust(n - 2),
}
}
#[pymodule]
fn rust_extensions(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(fibonacci_rust, m)?)?;
Ok(())
}
|
Learning Strategy and Resources
Recommended Learning Path
- Start with Tour of Rust - Interactive, hands-on introduction
- Read Rust by Example - Practical code patterns and idioms
- Study The Rust Book - Comprehensive language reference
- Practice with Rustlings - Small exercises to reinforce concepts
- Explore Little Book of Rust Macros - Advanced metaprogramming
- Read “Learn Rust the Dangerous Way” - Systems programming perspective
Key Concepts to Master
Essential Rust Concepts
- Ownership and Borrowing - Core memory safety guarantees
- Pattern Matching - Exhaustive case analysis with
match - Error Handling -
Result and Option types for safe error management - Traits - Rust’s interface system for polymorphism
- Lifetimes - Ensuring references remain valid
- Concurrency - Safe parallel programming with ownership
- Macros - Code generation and domain-specific languages
Why Rust Matters
Rust addresses fundamental problems in systems programming:
- Memory Safety: Eliminates entire classes of bugs at compile time
- Performance: Zero-cost abstractions with C/C++ level performance
- Concurrency: Fearless concurrency through type system guarantees
- Tooling: Excellent package manager (Cargo) and development experience
- Ecosystem: Growing collection of high-quality libraries (crates)
Rust Philosophy
Rust is a systems programming language that runs blazingly fast, prevents
segfaults, and guarantees thread safety.
This exploration of Rust learning resources demonstrates why Rust has become
essential for modern systems programming, offering both safety and performance
without compromise.
These Rust learning resources from my archive showcase the language’s evolution
from experimental to production-ready, with a rich ecosystem of educational
content and powerful development tools.