01. Hello Rust

📋 Jump to Takeaways

🎁 What if your compiler caught the bugs that other languages only discover in production — null dereferences, data races, use-after-free — all before your code ever runs?

Rust treats safety as a compile-time guarantee, not a runtime hope. Let's get it installed and write your first program.

Installing Rust

Rust uses a toolchain manager called rustup. It installs the compiler (rustc), the package manager (cargo), and keeps everything up to date with a single command.

# Install rustup (macOS/Linux)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Verify installation
rustc --version
# rustc 1.78.0 (9b00956e5 2024-04-29)

cargo --version
# cargo 1.78.0 (54d8815d0 2024-03-26)

On Windows, download the installer from rustup.rs. The process is the same — you get rustc and cargo ready to go.

Creating a Project with Cargo

Cargo is Rust's build system and package manager. You never compile files manually — Cargo handles everything.

# Create a new project
cargo new hello_rust

# What it generates:
# hello_rust/
# ├── Cargo.toml
# └── src/
#     └── main.rs

cargo new creates a ready-to-run project with the correct directory structure, a config file, and a starter program.

Project Structure

Every Rust project has two essential pieces: Cargo.toml and src/main.rs.

Cargo.toml — your project's manifest:

[package]
name = "hello_rust"
version = "0.1.0"
edition = "2021"

[dependencies]

This file declares your project name, version, Rust edition, and any external libraries (called "crates") you depend on.

src/main.rs — your entry point:

fn main() {
    println!("Hello, world!");
}
// Output: Hello, world!

The fn main() function is where every Rust program begins execution. No class boilerplate, no imports needed for basic programs.

Your First Program

Let's write a more interesting hello world that shows off Rust's formatting:

fn main() {
    let language = "Rust";
    let year = 2015;

    println!("Hello from {}!", language);
    println!("{} has been stable since {}.", language, year);
    println!("This program compiled with zero warnings.");
}
// Output:
// Hello from Rust!
// Rust has been stable since 2015.
// This program compiled with zero warnings.

The {} placeholders work like format strings in other languages. Rust replaces them with the values you pass, in order.

println! — The Print Macro

println! is a macro (notice the !). It prints text to the console with a newline at the end.

fn main() {
    // Basic printing
    println!("Simple text");
    // Output: Simple text

    // With variables
    let name = "developer";
    println!("Hello, {}", name);
    // Output: Hello, developer

    // Debug printing with {:?}
    println!("Debug: {:?}", (1, 2, 3));
    // Output: Debug: (1, 2, 3)

    // Print without newline
    print!("no ");
    print!("newline ");
    println!("here");
    // Output: no newline here
}

The {:?} formatter prints the "debug" representation of a value — useful for inspecting data structures during development.

Building and Running

Cargo gives you two main commands for executing your code:

# Compile and run in one step
cargo run
# Output: Hello, world!

# Just compile (faster for checking errors)
cargo build
# Creates: target/debug/hello_rust

# Compile with optimizations (for release)
cargo build --release
# Creates: target/release/hello_rust

# Check for errors without producing a binary
cargo check

Use cargo check during development — it's faster than cargo build because it skips code generation. Use cargo build --release when you want maximum performance.

Basic Types Preview

Rust is statically typed. Every value has a type known at compile time. Here's a preview of the fundamental types:

fn main() {
    let count: i32 = 42;          // 32-bit signed integer
    let temperature: f64 = 98.6;  // 64-bit floating point
    let active: bool = true;      // boolean
    let greeting: &str = "hi";    // string slice (borrowed text)

    println!("count: {}", count);           // count: 42
    println!("temp: {}", temperature);      // temp: 98.6
    println!("active: {}", active);         // active: true
    println!("greeting: {}", greeting);     // greeting: hi
}

i32 is the default integer type. f64 is the default float. You'll learn about all the numeric types in the next lesson — for now, know that Rust won't silently convert between them.

Comments

Rust supports line comments and documentation comments:

fn main() {
    // This is a line comment — the compiler ignores it

    /* This is a block comment.
       It can span multiple lines. */

    let x = 5; // Inline comment after code

    /// This is a doc comment (for the item below it).
    /// It supports Markdown and generates documentation.
}

Use // for regular comments. Use /// for documentation comments that appear in generated docs (via cargo doc). Block comments /* */ exist but are rarely used in practice.

Putting It All Together

Here's a complete program combining everything from this lesson:

// A simple Rust program demonstrating the basics
fn main() {
    // Declare variables with types
    let name: &str = "Rust";
    let version: f64 = 1.78;
    let is_fast: bool = true;
    let users: i32 = 3_000_000; // underscores for readability

    println!("Welcome to {}!", name);
    println!("Version: {}", version);
    println!("Fast: {}", is_fast);
    println!("Estimated users: {}", users);

    /* You can also use numeric separators
       to make large numbers readable */
    let big_number: i64 = 1_000_000_000;
    println!("One billion: {}", big_number);
    // Output: One billion: 1000000000
}

Run it with cargo run and you'll see the output instantly. The compiler checks everything before execution — if it compiles, a whole class of bugs is already eliminated.

Key Takeaways

  • Install Rust with rustup — it manages the compiler and cargo together
  • cargo new creates a project with Cargo.toml and src/main.rs
  • fn main() is the entry point of every Rust program
  • println! is a macro for formatted output — {} for values, {:?} for debug
  • cargo run compiles and executes; cargo check validates without building
  • Rust is statically typed: i32, f64, bool, &str are the basics
  • Use // for comments and /// for documentation

🎁 Next up: you'll discover that let creates variables that can never be changed — and why that's actually a powerful feature, not a limitation. Rust's approach to mutability prevents entire categories of bugs before they happen.

📝 Ready to test your knowledge?

Answer the quiz below to mark this lesson complete.

Spot something off? Report an issue

© 2026 ByteLearn.dev. Free courses for developers. · Privacy