Rust Syntax and Hello World
Learn how a Rust program is structured and understand the syntax you will see in every Rust project: fn main(), statements, expressions, blocks, comments, macros, formatting and compiler feedback.
What you will learn
- How Rust source files are structured
- What fn main() means
- How println! and other macros work
- Statements versus expressions
- Semicolons and return values
- Code blocks and scope
- Comments and documentation comments
- String formatting and placeholders
- How to compile and run syntax examples
- How to read basic compiler errors
1. Create a Rust project
cargo new rust_syntax_lab cd rust_syntax_lab cargo runCargo creates a package containing a Cargo.toml manifest and a src/main.rs source file. A new binary project starts with a minimal Hello World application.
2. Your first Rust program
fn main() { println!("Hello, world!"); }Run it:
cargo runExpected output:
Hello, world!3. Understanding fn main()
Every normal Rust binary has an entry point named main. Execution begins there.
fn main() { // program starts here }| Syntax | Meaning |
|---|---|
| fn | Declares a function. |
| main | The entry-point function for a binary program. |
| () | The function takes no parameters. |
| { ... } | The function body is a code block. |
Rust convention uses snake_case for function and variable names:
fn calculate_total() { println!("Calculating..."); }4. What is println! ?
println! prints formatted text followed by a newline.
println!("Welcome to Rust!");The exclamation mark is important: println! is a macro, not an ordinary function call. Rust macros can accept syntax that ordinary functions cannot and are expanded by the compiler.
println!
Prints text and adds a newline.
println!("Hello");print!
Prints without automatically adding a newline.
print!("Hello "); print!("Rust");eprintln!
Prints to standard error, useful for errors and diagnostics.
eprintln!("Something went wrong");5. Formatting output
Rust formatting macros support placeholders.
fn main() { let language = "Rust"; let year = 2015; println!("I am learning {language}."); println!("Rust 1.0 was released in {year}."); }You can also use positional placeholders:
println!("{} + {} = {}", 10, 20, 30);Named formatting can make complex messages clearer:
println!( "User {name} completed chapter {chapter}", name = "Alex", chapter = 2 );Debug formatting
let ports = [80, 443, 8080]; println!("{:?}", ports);Pretty debug formatting:
println!("{:#?}", ports);6. Statements and expressions
This distinction is one of the most important parts of Rust syntax.
Statements
A statement performs an action and normally does not produce a value that can be used by the surrounding expression.
let x = 10; let y = 20;Expressions
Expressions evaluate to a value:
5 + 5 x * 2 { let value = 4; value + 1 }A block can therefore produce a value:
fn main() { let answer = { let x = 20; x + 22 }; println!("Answer: {answer}"); }The last line x + 22 has no semicolon. It becomes the block's resulting value.
7. Why semicolons matter
fn add_one(x: i32) -> i32 { x + 1 }The final expression returns the value automatically. This is valid Rust.
This version is different:
fn add_one(x: i32) -> i32 { x + 1; }The semicolon suppresses the expression value, so the compiler reports a type mismatch because the function promises to return i32.
8. Code blocks and scope
Curly braces create blocks. Variables declared in a block normally live only inside that scope.
fn main() { let outside = 10; { let inside = 20; println!("outside={outside}, inside={inside}"); } println!("outside={outside}"); // println!("{inside}"); // compiler error }9. Comments in Rust
Single-line comment
// This is a comment println!("Hello");Multiple lines
// First line // Second line // Third lineBlock comments
/* This is a block comment. It can span multiple lines. */Documentation comments
Rust also has documentation comments that can become generated API documentation:
/// Adds two integer values. fn add(a: i32, b: i32) -> i32 { a + b }Generate project documentation with:
cargo doc --open10. Basic naming conventions
| Item | Common Rust style | Example |
|---|---|---|
| Variables | snake_case | user_name |
| Functions | snake_case | calculate_total |
| Types / structs / enums | UpperCamelCase | UserProfile |
| Constants | SCREAMING_SNAKE_CASE | MAX_RETRIES |
11. A complete syntax example
fn greeting(name: &str) -> String { format!("Hello, {name}!") } fn main() { let user = "Kaushik"; let message = greeting(user); println!("{message}"); let result = { let a = 10; let b = 20; a + b }; println!("Calculation result: {result}"); }Run:
cargo runExpected:
Hello, Kaushik! Calculation result: 3012. Compile without running
cargo buildFor faster compile-time feedback while developing:
cargo checkcargo check is useful when you want Rust's compiler diagnostics without producing the final executable.
13. Read compiler errors instead of fighting them
Rust compiler diagnostics frequently show the file, line, problematic code and a suggested correction.
Try this intentionally broken example:
fn main() { println!("Hello") println!("Rust"); }The missing semicolon between macro invocations causes a compile error. Run:
cargo checkThen read the diagnostic from top to bottom. During Rust learning, compiler messages are effectively an interactive tutor.
14. Formatting Rust code automatically
Instead of manually aligning code, use Rust's formatter:
cargo fmtCheck formatting without changing files:
cargo fmt --check15. Lint your code with Clippy
cargo clippyClippy provides additional recommendations for correctness, readability and idiomatic Rust.
16. Mini lab
Create this program without copying the final answer first:
- Create a project named chapter2_lab .
- Store your name and a technology in variables.
- Print both values using captured formatting.
- Create an inner block that calculates 15 * 4 .
- Assign the result of that block to a variable.
- Print the result.
- Add a documentation comment above a helper function.
- Run cargo fmt , cargo check , cargo clippy and cargo run .
Example solution
/// Creates a short learning message. fn learning_message(name: &str, technology: &str) -> String { format!("{name} is learning {technology}") } fn main() { let name = "Kaushik"; let technology = "Rust"; println!("{}", learning_message(name, technology)); let result = { let value = 15; value * 4 }; println!("15 × 4 = {result}"); }17. Common beginner mistakes
| Mistake | Fix |
|---|---|
| Writing println() | Use the macro syntax println!() . |
| Forgetting semicolons between statements | Add ; where the statement should end. |
| Adding a semicolon to a return expression | Remove it when the final expression should provide a function/block value. |
| Using a variable outside its scope | Move the declaration to a wider scope or restructure the code. |
| Ignoring compiler output | Read the first compiler error carefully before addressing later cascading errors. |
18. Recommended workflow for every example
cargo fmt cargo check cargo clippy cargo test cargo runRust syntax cheat sheet
// Function fn greet() { println!("Hello!"); } // Variable let name = "Rust"; // Code block returning a value let x = { let y = 5; y + 1 }; // Function returning a value fn double(value: i32) -> i32 { value * 2 } // Comment // one line // Documentation comment /// Documents the next item.Official references
This chapter follows the current Rust language and Cargo documentation. Rust's official book introduces variables, data types, functions, comments and control flow as common programming concepts, while Cargo provides the standard package/build workflow.
- The Rust Programming Language — Common Programming Concepts
- The Rust Programming Language — Functions
- The Cargo Book — First Steps with Cargo
Join the discussion
0 CommentsAsk questions, add context, or share what worked.
More from Melochip Editorial
Learn what Playwright testing is, why modern QA teams use it, how testers can get started, and the major types...
7 min read · Sep 19, 2026
Learn how Kubernetes Deployments and ReplicaSets work with practical YAML, scaling, self-healing, rolling upda...
7 min read · Sep 17, 2026
Learn Kubernetes security best practices with RBAC, Secrets, ServiceAccounts, Pod securityContext, NetworkPoli...
6 min read · Sep 17, 2026Related articles
Learn Linux from the ground up with simple explanations of the kernel, distributions, filesystem, commands, pe...
4 min read · Updated Oct 1, 2026
Learn what Playwright testing is, why modern QA teams use it, how testers can get started, and the major types...
7 min read · Sep 19, 2026
Learn how Kubernetes Deployments and ReplicaSets work with practical YAML, scaling, self-healing, rolling upda...
7 min read · Sep 17, 2026
Learn Kubernetes security best practices with RBAC, Secrets, ServiceAccounts, Pod securityContext, NetworkPoli...
6 min read · Sep 17, 2026Stay in the loop. Get new Melochip articles
Receive Melochip article updates when new articles are available. Explicit opt-in only.
No comments yet. Start the discussion.