Your First Rust Program
Reading and extending the default "Hello, world!" program to understand Rust's basic syntax.
2 min read
Every new Cargo project comes with a working program already in src/main.rs:
fn main() {
println!("Hello, world!");
}Run it with cargo run and you'll see Hello, world! printed to your terminal. Small as it is, this line touches most of Rust's basic syntax.
Breaking it down
fn main() declares a function named main — the entry point every Rust binary needs. When you run the compiled program, this is the first code that executes.
println! looks like a function call, but the ! marks it as a macro, not a function. Macros generate code at compile time rather than running at runtime; println! specifically expands into the code needed to format and print a string, which is why it can accept a variable number of arguments and check the format string against them at compile time. You don't need to understand macro internals yet — just recognize the ! and know it's a macro call.
The curly braces {} inside the string are placeholders, filled in by additional arguments:
fn main() {
let name = "Rustacean";
let year = 2015;
println!("Hello, {}! Rust hit 1.0 in {}.", name, year);
}You can also name the placeholders directly, which reads better once you have more than one or two:
println!("Hello, {name}! Rust hit 1.0 in {year}.");Statements end with semicolons
Rust statements end with ;, similar to C, C++, or JavaScript:
let x = 5;
let y = 10;
println!("{}", x + y);Leaving off a semicolon where one is expected produces a compiler error — but leaving it off deliberately at the end of a function means something different, which the next lesson covers when you start writing your own functions.
Comments
// A single-line comment
/* A block comment,
spanning multiple lines */
fn main() {
// This explains what the next line does
println!("Comments are ignored by the compiler");
}Compiling without Cargo
It's worth knowing what Cargo is doing under the hood at least once. You can compile a single file directly with rustc:
rustc main.rs
./mainThis produces a native executable — no separate runtime or interpreter required to run it, unlike Python or Node.js scripts. That's part of why Rust binaries are easy to deploy: copy the file, run it.
From here, every following lesson builds on this same shape — a main function, let for values, and println! for output — while introducing the type system, control flow, and eventually ownership that make Rust distinct from the languages you may already know.
Test what you just learned
4 quick questions. Get all of them right to unlock the next lesson.
You can take the quiz without an account — logging in just lets your result count toward your progress.