This cheat sheet gives grades 11-12 students a quick reference for reading and writing basic Rust syntax. Rust is used for fast, safe systems programming, so students need to understand how its rules differ from languages like Python, JavaScript, or Java. The reference focuses on syntax patterns that appear often in beginner Rust programs, including variables, functions, conditionals, loops, collections, and types.
Key Facts
- Variables are immutable by default, so use let x = 5; for a fixed value and let mut x = 5; when the value must change.
- A function is declared with fn name(parameter: Type) -> ReturnType { expression }, such as fn square(n: i32) -> i32 { n * n }.
- Rust uses type annotations such as i32, f64, bool, char, String, and Vec<T>, but it can often infer types from values.
- An if expression must use a bool condition, and it can return a value with syntax like let result = if score >= 60 { "pass" } else { "fail" };.
- A for loop over a range uses start..end to exclude the end value and start..=end to include it, such as for i in 1..=5 { println!("{}", i); }.
- Ownership means each value has one owner at a time, and assignment to another variable can move the value unless the type implements Copy.
- Borrowing uses references, with &value for an immutable borrow and &mut value for a mutable borrow.
- Pattern matching uses match value { pattern => result, _ => default }, and every possible case must be handled.
Vocabulary
- Ownership
- Ownership is Rust's rule that each value has one variable responsible for managing its memory.
- Borrowing
- Borrowing means using a reference to a value without taking ownership of that value.
- Mutable
- A mutable variable or reference can be changed after it is created.
- Struct
- A struct is a custom data type that groups named fields into one value.
- Enum
- An enum is a custom type whose value must be one of several named variants.
- Result
- Result<T, E> is a type used for operations that can either succeed with Ok(T) or fail with Err(E).
Common Mistakes to Avoid
- Forgetting mut in let x = 3; x = 4; is wrong because Rust variables cannot be reassigned unless they are declared with let mut.
- Using a moved value after let b = a; is wrong for many heap-owned types because ownership may transfer from a to b.
- Passing &mut value while another reference is still active is wrong because Rust prevents simultaneous mutable and immutable access to avoid data races.
- Putting a semicolon after the final expression in a return-value function can be wrong because n * n returns a value, but n * n; returns ().
- Leaving out the default _ arm in match can be wrong when not all possible cases are covered, because Rust requires exhaustive pattern matching.
Practice Questions
- 1 What is printed by this code: let mut x = 4; x += 3; println!("{}", x);
- 2 How many numbers are printed by this loop: for i in 2..7 { println!("{}", i); }
- 3 Write a Rust function header and body for a function named double that takes an i32 and returns that number multiplied by 2.
- 4 Explain why Rust allows many immutable references to a value but only one mutable reference at a time.
Understanding Rust Syntax Quick Reference
Rust becomes easier once you follow the life of each piece of data. Small values such as whole numbers are usually quick to copy. Larger data, especially text that can grow, may live in heap memory.
A variable then holds responsibility for cleaning up that memory when its scope ends. This automatic cleanup avoids many memory leaks without needing a garbage collector. It creates an important habit for programmers.
Before passing a value into a function or storing it elsewhere, think about whether the original variable should still be usable afterward. If it should, pass a reference or make a deliberate copy when copying is appropriate.
References let code inspect or change data without taking responsibility for it. Rust checks these references before the program runs. Many rules come from one safety idea.
Code should not change data while some other part is reading it in a way that could become unsafe. A program can have several read only references to the same value. It can have one changeable reference when no read only references are active.
This may feel strict at first, yet it prevents bugs that can appear only rarely in other languages. These bugs matter in apps, games, operating systems, and programs that handle many tasks at once.
Structs and enums help model real information clearly. A struct groups related fields into one custom type, such as a student record or a position in a game. An enum represents one choice from a defined set, such as a traffic light state or the result of an operation.
Enums often carry extra data inside each case. This makes invalid states harder to represent. For example, a value that may be present or absent can use Option rather than a special fake value.
A task that can succeed or fail can use Result. Pattern matching then forces the program to deal with each meaningful case instead of quietly ignoring failure.
Compiler messages are part of normal Rust programming, not evidence that a learner has failed. The compiler often identifies the exact line involved and explains whether a value was moved, borrowed too long, or given the wrong type. Read the first error carefully before trying several changes.
Build tiny examples when a rule seems confusing. Test one idea involving scope, a function call, or a match branch. Pay close attention to block boundaries because a variable is dropped when its scope finishes.
In school projects, these habits lead to code that is easier to test and safer to extend. Rust asks for clear decisions early, which saves time when programs grow larger.