Lab: Core syntax review
Consolidate your Rust core syntax knowledge with a quiz covering variables, functions, control flow, and ownership.
- Recall the key rules for variables, functions, control flow, and ownership
- Identify correct and incorrect Rust syntax from short snippets
- Predict compiler behaviour before running code
This is an optional lab. No new concepts — just a chance to consolidate what you've learned across the core syntax module. Work through the quiz sections, then try the coding challenges in your own editor.
Rust's compiler is your best teacher — but only if you read what it says. This lab is designed to make you predict what the compiler will do before you run anything. That habit, more than any other, speeds up the learning curve.
Section 1 — Variables and types
Knowledge check
- 1.What is the output of this program?
fn main() { let x = 10; let x = x + 5; println!("{}", x); } - 2.Which literal correctly creates a char in Rust?
- 3.In Rust, you must declare a variable with mut before the compiler will allow you to change its value.
Section 2 — Functions
Knowledge check
- 1.What does this function return?
fn mystery(x: i32) -> i32 { let y = x * 2; y + 1; } - 2.In Rust, the return keyword is required to exit a function early.
- 3.Rust infers parameter types in function definitions, so
fn double(x) -> i32is valid.
Section 3 — Control flow
Knowledge check
- 1.How many times does the loop body execute?
for i in 1..=4 { println!("{}", i); } - 2.Which loop form lets you return a value from the loop itself?
- 3.Which of these are valid uses of if as an expression in Rust?
Section 4 — Ownership
Knowledge check
- 1.What does the Rust compiler do when you use a String variable after it has been moved?
let a = String::from("hi"); let b = a; println!("{}", a); - 2.Assigning an i32 variable to another variable moves ownership, making the original unusable.
- 3.When should you use .clone() on a String?
Coding challenges
These won't run in the browser — Rust needs a local compiler. Open your hello-world project and try each one.
Challenge 1: FizzBuzz
Write a fizzbuzz function that takes an i32 and returns a String: "Fizz" if divisible by 3, "Buzz" if divisible by 5, "FizzBuzz" if both, and the number as a string otherwise. Use it in a for loop from 1 to 20.
Hint: format!("{}", n) turns an integer into a String. The % operator gives you the remainder. For FizzBuzz, check the combined case first.
Challenge 2: Ownership transfer
Write two functions: greet(name: String) -> String that takes ownership of a name and returns a greeting string, and main that calls it. Notice that name is gone after the call. Then change greet to take &str instead (a string slice — a peek at borrowing) and see what the compiler suggests.
Challenge 3: Fibonacci
Write a function fibonacci(n: u32) -> u64 that returns the nth Fibonacci number. Use a while loop, two mutable variables to track the previous two values, and a counter.
When the agent's away
After this module, the most productive thing you can do is write small programs from scratch:
cargo new practice
cd practice
# edit src/main.rs, run cargo run, read the errorsThe Rust Book (available free at https://doc.rust-lang.org/book/) covers everything in this module and more. Run rustup doc --book to open it offline.
Where to go next
You've finished the core syntax module. The next step is the intermediate track — references and borrowing, structs and enums, pattern matching with match, and Result/Option for error handling. These are the tools that make Rust programs feel complete.