Rust Basics
Learn the fundamental building blocks of Rust: variables, types, operators, and basic syntax.
What’s in This Section
Section titled “What’s in This Section”- Variables and Mutability - let, mut, shadowing, constants
- Basic Types - Integers, floats, booleans, characters, tuples
- Operators - Arithmetic, comparison, logical, and more
- Comments - Code comments and documentation
- Output and Formatting - println!, print!, formatting
Learning Objectives
Section titled “Learning Objectives”By the end of this section, you will:
- Understand Rust’s immutability-by-default philosophy
- Know all basic data types and when to use them
- Use type annotations and type inference
- Perform arithmetic and logical operations
- Write clear comments and documentation
- Format output with println! macro
Time Estimate
Section titled “Time Estimate”- Reading: 60-90 minutes
- Hands-on Practice: 45-60 minutes
- Exercises: 30-45 minutes
- Total: 2.5-3 hours
Quick Start Path
Section titled “Quick Start Path”If you want to jump right in:
Then come back for operators and comments.
Detailed Learning Path
Section titled “Detailed Learning Path”Recommended Order
Section titled “Recommended Order”1. Variables and Mutability (the big difference!) ↓2. Basic Types (integers, floats, etc.) ↓3. Operators (arithmetic, comparison) ↓4. Comments (documentation) ↓5. Output and Formatting (println!)All topics are interconnected, sequential reading recommended.
What You’ll Learn
Section titled “What You’ll Learn”Variables: Immutable by Default
Section titled “Variables: Immutable by Default”The biggest difference from TypeScript/JavaScript:
TypeScript:
let x = 5; // mutablex = 6; // OKRust:
let x = 5; // immutable by default!x = 6; // Compile error!
let mut y = 5; // explicitly mutabley = 6; // OKKey insight: Rust makes you think about mutability upfront.
Rich Type System
Section titled “Rich Type System”TypeScript:
let x: number = 42; // One number typelet y = 3.14; // Also numberRust:
let x: i32 = 42; // 32-bit signed integerlet y: f64 = 3.14; // 64-bit floatlet z: u8 = 255; // 8-bit unsigned integerWhy: More control over memory and performance.
Type Inference
Section titled “Type Inference”Both languages have it:
let x = 5; // TypeScript infers: numberlet x = 5; // Rust infers: i32But Rust’s inference goes further in complex scenarios!
Operators
Section titled “Operators”Mostly the same:
// TypeScriptlet sum = 5 + 3;let is_equal = x === y;// Rustlet sum = 5 + 3;let is_equal = x == y; // Note: no ===, just ==Comments
Section titled “Comments”Similar syntax:
// TypeScript// Single line comment/* Multi-line comment */
/** JSDoc documentation */// Rust// Single line comment/* Multi-line comment */
/// Documentation comment (generates docs!)Formatted Output
Section titled “Formatted Output”Different, but does more:
// TypeScriptconsole.log(`Hello, ${name}!`);console.log("x =", x, "y =", y);// Rustprintln!("Hello, {}!", name);println!("x = {} y = {}", x, y);Key Differences from TypeScript
Section titled “Key Differences from TypeScript”1. Mutability
Section titled “1. Mutability”| Aspect | TypeScript | Rust |
|---|---|---|
| Default | Mutable (let) | Immutable (let) |
| Make immutable | Use const | Default! |
| Make mutable | Default! | Use let mut |
| Reassignment | Always allowed | Only with mut |
2. Type System
Section titled “2. Type System”| Feature | TypeScript | Rust |
|---|---|---|
| Number types | number | i8, i32, f64… |
| Integer types | number | 12 different types! |
| Type annotations | : Type | : Type (same!) |
| Type inference | Good | Excellent |
| Null safety | strict mode | No null at all (Option<T>) |
| Escape hatches | any (opt-out) | unsafe / dyn Any (rare) |
3. Variables
Section titled “3. Variables”TypeScript:
let x = 5;let x = 10; // Error: cannot redeclareRust:
let x = 5;let x = 10; // OK - this is "shadowing"!Shadowing is a Rust feature that lets you reuse variable names.
4. Constants
Section titled “4. Constants”TypeScript:
const MAX_SIZE = 100; // Runtime constantRust:
const MAX_SIZE: u32 = 100; // Compile-time constant// ^^^ Must have type annotation!Important Concepts
Section titled “Important Concepts”Immutability by Default
Section titled “Immutability by Default”Why does Rust do this?
- Safety: Prevents accidental modification
- Concurrency: Immutable data is thread-safe
- Optimization: Compiler can optimize better
- Intent: Makes mutability explicit
Coming from JavaScript, this feels backwards at first!
// JavaScript - everything is mutablelet x = 5;x = 6; // No problem// Rust - explicit mutabilitylet x = 5;// x = 6; // Won't compile
let mut y = 5;y = 6; // OKYou’ll get used to it! After a week, you’ll appreciate it.
Type Annotations vs Inference
Section titled “Type Annotations vs Inference”Rust is smart about types:
let x = 5; // Inferred as i32let y: u8 = 5; // Explicitly u8let z = 5u8; // Suffix notationWhen you need annotations:
// Compiler can't inferlet numbers: Vec<i32> = Vec::new();
// Multiple possible typeslet guess: u32 = "42".parse().expect("Not a number!");Expressions vs Statements
Section titled “Expressions vs Statements”Everything in Rust is an expression (almost):
let x = { let y = 3; y + 1 // No semicolon - this is the return value!};// x is now 4Compare to TypeScript:
// TypeScript - blocks don't return valueslet x = (() => { let y = 3; return y + 1;})();Your Goals for This Section
Section titled “Your Goals for This Section”Minimum Goals
Section titled “Minimum Goals”- Understand
letvslet mut - Know the basic integer types (
i32,u32, etc.) - Use
println!with formatting - Write simple arithmetic expressions
Stretch Goals
Section titled “Stretch Goals”- Understand shadowing vs reassignment
- Know when to use each integer type
- Use all comparison operators
- Write documentation comments
- Use advanced formatting (debug, alignment)
Common First-Time Issues
Section titled “Common First-Time Issues””cannot assign twice to immutable variable”
Section titled “”cannot assign twice to immutable variable””let x = 5;x = 6; // Error!Solution: Add mut:
let mut x = 5;x = 6; // OK“type annotations needed”
Section titled ““type annotations needed””let x = Vec::new(); // What type?Solution: Add type annotation:
let x: Vec<i32> = Vec::new(); // OKInteger overflow
Section titled “Integer overflow”let x: u8 = 255;let y = x + 1; // Compile error: this arithmetic operation will overflowWhen both operands are constants, the compiler catches the overflow at compile
time (error: this arithmetic operation will overflow). To see the runtime
behavior, the overflow has to involve a value the compiler can’t fold away:
let mut x: u8 = 255;x += 1; // Panics in debug mode; silently wraps to 0 in release modeIn debug builds this panics with attempt to add with overflow; in release
builds the check is removed and the value wraps around to 0.
Solution: When you want wraparound, use the explicit wrapping/saturating
arithmetic methods (wrapping_add, saturating_add, checked_add); we’ll
cover these later.
Section Overview
Section titled “Section Overview”What Makes This Section Important
Section titled “What Makes This Section Important”These are the building blocks! Everything in Rust builds on:
- Variables and mutability
- The type system
- Basic operations
Master these, and the rest becomes easier.
How This Relates to Later Sections
Section titled “How This Relates to Later Sections”- Section 03 (Functions): Use these types as parameters
- Section 05 (Ownership): Immutability is key to ownership
- Section 06 (Data Structures): Compose basic types
- Section 08 (Error Handling): Type system enables Result/Option
Comparison to TypeScript Fundamentals
Section titled “Comparison to TypeScript Fundamentals”| Concept | TypeScript Section | Rust Section | Difficulty |
|---|---|---|---|
| Variables | Day 1 | Day 1 | Medium |
| Types | Day 1-2 | Day 1-2 | Medium |
| Operators | Day 1 | Day 1 | Easy |
| Mutability | Not emphasized | Critical | Hard |
| Type safety | Optional | Mandatory | Medium |
The mutability concept is the hardest part for JS/TS developers.
Ready to Begin?
Section titled “Ready to Begin?”Let’s start with the most important concept: variables and mutability!
Or jump to:
Frequently asked questions
Section titled “Frequently asked questions”Are Rust variables mutable like JavaScript’s let?
Section titled “Are Rust variables mutable like JavaScript’s let?”No. let x = 5; is immutable, and you opt into mutation with let mut x = 5;. This is the reverse of JavaScript, where let is reassignable and only const locks a binding. Rust’s const is a separate, always-immutable, compile-time constant. See Variables and Mutability.
Why does Rust have so many number types instead of one number?
Section titled “Why does Rust have so many number types instead of one number?”JavaScript’s single f64 loses integer precision past 2^53 and hides cost. Rust’s sized integers (i32, u64, usize, …) and floats (f32, f64) make range, signedness, and memory explicit. Constant overflow is rejected, debug integer overflow panics by default, and optimized release builds wrap unless overflow checks are enabled; use checked_*, saturating_*, or wrapping_* when the policy matters. See Basic Types.
What is shadowing?
Section titled “What is shadowing?”Re-declaring a name with let: let id = "5"; let id: i32 = id.parse()?;. The new binding can change type and reuses the name, unlike reassignment, which cannot. It is handy for refining a value through a few steps without inventing new names. See Variables and Mutability.