Lesson 4
Basic macros
println!, format!, vec!, and assert! — the four macros you will see in almost every Rust program.
Four macros you already used, now explained
You already wrote println! in almost every example in this course, and
every exercise checked your solution with assert_eq!, without ever
explaining what they are or why they carry !. This lesson closes that
gap, and along the way closes out module 1 entirely: vec! delivers on
the promise “Variables, mutability and types” made about showing a
collection that can actually grow.
println!, format!, vec!, and assert! are macros, not functions:
that is why they carry !. A macro expands at compile time, so it can
accept a variable number of arguments and check your format string before
the program even runs.
You will go through four stations, one per macro: println!, format!,
vec!, and the assert! family.
Exercise 01 · Score report
Build a report with vec! and format!.
The starter already declares the signature. Complete the body with a Vec, a for loop to sum, and format! to build the final text.
Objective
Complete build_report so it returns a String in the format "scores: [a, b, c], total: sum", using vec!, a for loop to sum, and format!.
Implement
Replace `todo!` with `vec![a, b, c]`, a `for` loop that sums, and `format!` with `{scores:?}` and `{sum}`.
Function 01
Build the report
Group the three values in a Vec, sum them with a for loop, and format the result with format!.
pub fn build_report(a: i32, b: i32, c: i32) -> String {
todo!("build a Vec with vec![a, b, c], sum it with a for loop, and format the result")
}Check
Run the visible cases and use the diagnostic to correct the code.
Visible tests
Modify the code before running the tests.
Help
View progressive hints or compare with the solution.
/// Builds a report string from three scores using vec! and format!.
#[must_use]
pub fn build_report(a: i32, b: i32, c: i32) -> String {
let scores = vec![a, b, c];
let mut sum = 0;
for score in &scores {
sum += score;
}
format!("scores: {scores:?}, total: {sum}")
}
// Playground entry point for this example.
fn main() {
println!("{}", build_report(10, 20, 30));
}Summary
println!,format!,vec!, andassert!are macros, not functions: that is why they carry!.{}usesDisplay(human reading);{:?}usesDebug(debugging), and it is the only one that works with collections.format!builds aStringwith the same syntax asprintln!, without printing anything.vec!creates aVecof variable size; unlike an array, it supports.push()and.pop().assert!,assert_eq!, andassert_ne!panic with a formatted message when the check fails.assert_eq!/assert_ne!require the type to implementDebug, to be able to print both sides if they fail.