Skip to content

Rust Quick Start

Overview

This chapter introduces you to Rust's basic syntax and core concepts through actual code examples. We'll start from Hello World and gradually build more complex programs.

🚀 Hello World

First Program

rust
// src/main.rs
fn main() {
    println!("Hello, World!");
    println!("Hello, Rust!");

    // Formatted output
    let name = "Rust";
    let year = 2023;
    println!("Welcome to {} world! It's {} year.", name, year);
}
bash
# Run program
cargo run
# Output:
# Hello, World!
# Hello, Rust!
# Welcome to Rust world! It's 2023 year.

Variables and Constants

rust
fn main() {
    // Immutable variable (default)
    let x = 5;
    println!("Value of x is: {}", x);

    // x = 6; // Compile error! Immutable variables cannot be reassigned

    // Mutable variable
    let mut y = 5;
    println!("Value of y is: {}", y);
    y = 6; // Can modify
    println!("Now value of y is: {}", y);

    // Variable shadowing
    let x = x + 1; // Create new variable, shadow previous x
    println!("Shadowed value of x is: {}", x);

    // Constant
    const MAX_POINTS: u32 = 100_000;
    println!("Max score: {}", MAX_POINTS);
}

📊 Basic Data Types

Numeric Types

rust
fn number_types() {
    // Integer types
    let small: i8 = -128;
    let big: i64 = 1_000_000;
    let unsigned: u32 = 42;

    // Floating point types
    let pi: f64 = 3.14159;
    let e: f32 = 2.71828;

    // Type inference
    let guess = 42; // Default i32
    let float_guess = 3.14; // Default f64

    println!("Integers: {}, {}, {}", small, big, unsigned);
    println!("Floats: {}, {}", pi, e);
    println!("Inferred: {}, {}", guess, float_guess);
}

Boolean and Character Types

rust
fn bool_and_char() {
    // Boolean type
    let is_rust_awesome = true;
    let is_difficult: bool = false;

    // Character type (Unicode)
    let letter = 'A';
    let emoji = '😀';
    let chinese = '中';

    println!("Boolean values: {}, {}", is_rust_awesome, is_difficult);
    println!("Characters: {}, {}, {}", letter, emoji, chinese);
}

Compound Types

rust
fn compound_types() {
    // Tuple
    let tuple: (i32, f64, char) = (42, 3.14, 'R');
    let (x, y, z) = tuple; // Destructuring
    println!("Tuple: {}, {}, {}", x, y, z);
    println!("Access tuple: {}", tuple.0);

    // Array
    let array = [1, 2, 3, 4, 5];
    let months = ["January", "February", "March"];
    let zeros = [0; 5]; // [0, 0, 0, 0, 0]

    println!("Array: {:?}", array);
    println!("First month: {}", months[0]);
    println!("All zeros array: {:?}", zeros);
}

🔧 Function Basics

Function Definition and Calling

rust
fn main() {
    println!("Main function started");

    // Call functions
    greet();
    let result = add(5, 3);
    println!("5 + 3 = {}", result);

    // Functions with return values
    let (sum, product) = calculate(4, 6);
    println!("4 + 6 = {}, 4 * 6 = {}", sum, product);
}

// No parameters, no return value
fn greet() {
    println!("Hello, greetings from function!");
}

// Has parameters and return value
fn add(a: i32, b: i32) -> i32 {
    a + b // Expression, no semicolon
}

// Multiple return values (using tuple)
fn calculate(x: i32, y: i32) -> (i32, i32) {
    (x + y, x * y)
}

// Function with statements
fn verbose_add(a: i32, b: i32) -> i32 {
    println!("Calculating {} + {}", a, b);
    let result = a + b; // Statement
    result // Expression
}

🎛️ Control Flow

Conditional Statements

rust
fn conditionals() {
    let number = 6;

    // if expression
    if number % 4 == 0 {
        println!("{} is divisible by 4", number);
    } else if number % 3 == 0 {
        println!("{} is divisible by 3", number);
    } else if number % 2 == 0 {
        println!("{} is divisible by 2", number);
    } else {
        println!("{} is not divisible by 2, 3, 4", number);
    }

    // if expression assignment
    let condition = true;
    let result = if condition { 5 } else { 6 };
    println!("Result is: {}", result);

    // Complex conditions
    let age = 18;
    let has_license = true;

    if age >= 18 && has_license {
        println!("Can drive");
    } else {
        println!("Cannot drive");
    }
}

Loops

rust
fn loops() {
    // loop infinite loop
    let mut counter = 0;
    loop {
        counter += 1;
        if counter == 3 {
            println!("Skip 3");
            continue;
        }
        if counter == 6 {
            println!("End loop");
            break;
        }
        println!("Counter: {}", counter);
    }

    // while conditional loop
    let mut number = 3;
    while number != 0 {
        println!("Countdown: {}", number);
        number -= 1;
    }
    println!("Launch!");

    // for iteration loop
    let array = [10, 20, 30, 40, 50];
    for element in array.iter() {
        println!("Value is: {}", element);
    }

    // Range loop
    for number in 1..4 {
        println!("Number: {}", number);
    }

    // Loop with index
    for (index, value) in array.iter().enumerate() {
        println!("Value at index {} is {}", index, value);
    }
}

📦 Ownership Introduction

Basic Ownership

rust
fn ownership_basics() {
    // Ownership transfer
    let s1 = String::from("hello");
    let s2 = s1; // s1's ownership transfers to s2

    // println!("{}", s1); // Compile error! s1 is no longer valid
    println!("{}", s2); // Normal

    // Cloning
    let s3 = String::from("world");
    let s4 = s3.clone(); // Deep copy
    println!("s3: {}, s4: {}", s3, s4); // Both valid

    // Copy for basic types
    let x = 5;
    let y = x; // Copy trait, both valid
    println!("x: {}, y: {}", x, y);
}

fn ownership_functions() {
    let s = String::from("hello");
    takes_ownership(s); // s's value moves into function
    // println!("{}", s); // Compile error! s is no longer valid

    let x = 5;
    makes_copy(x); // i32 is Copy, so x is still valid
    println!("{}", x); // Normal

    let s1 = gives_ownership(); // Function return value moves to s1
    println!("{}", s1);

    let s2 = String::from("world");
    let s3 = takes_and_gives_back(s2); // s2 moves into function, return value moves to s3
    println!("{}", s3);
}

fn takes_ownership(some_string: String) {
    println!("{}", some_string);
} // some_string goes out of scope and is dropped

fn makes_copy(some_integer: i32) {
    println!("{}", some_integer);
} // some_integer goes out of scope, nothing special happens

fn gives_ownership() -> String {
    let some_string = String::from("hello");
    some_string // Return, ownership moves to calling function
}

fn takes_and_gives_back(a_string: String) -> String {
    a_string // Return, ownership moves to calling function
}

References and Borrowing

rust
fn references_and_borrowing() {
    let s1 = String::from("hello");

    // Immutable reference
    let len = calculate_length(&s1);
    println!("Length of '{}' is {}", s1, len); // s1 is still valid

    // Mutable reference
    let mut s2 = String::from("hello");
    change(&mut s2);
    println!("After modification: {}", s2);

    // Multiple immutable references
    let r1 = &s1;
    let r2 = &s1;
    println!("{} and {}", r1, r2); // Normal

    // Mutable reference restrictions
    let mut s3 = String::from("hello");
    let r3 = &mut s3;
    // let r4 = &mut s3; // Compile error! Only one mutable reference allowed at a time
    println!("{}", r3);
}

fn calculate_length(s: &String) -> usize {
    s.len()
} // s goes out of scope, but since it doesn't own the referenced value, nothing happens

fn change(some_string: &mut String) {
    some_string.push_str(", world");
}

🏗️ Struct Introduction

Defining and Using Structs

rust
// Define struct
#[derive(Debug)] // Allow formatting with {:?}
struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}

// Tuple struct
#[derive(Debug)]
struct Point(i32, i32, i32);

fn struct_examples() {
    // Create struct instance
    let user1 = User {
        email: String::from("user@example.com"),
        username: String::from("someuser"),
        active: true,
        sign_in_count: 1,
    };

    println!("User: {:?}", user1);
    println!("Username: {}", user1.username);

    // Mutable struct
    let mut user2 = User {
        email: String::from("another@example.com"),
        username: String::from("anotherusername"),
        active: true,
        sign_in_count: 1,
    };

    user2.email = String::from("newemail@example.com");
    println!("Updated email: {}", user2.email);

    // Struct update syntax
    let user3 = User {
        email: String::from("third@example.com"),
        username: String::from("thirduser"),
        ..user1 // Rest of fields same as user1
    };

    println!("User3: {:?}", user3);

    // Tuple struct
    let point = Point(1, 2, 3);
    println!("Point: {:?}", point);
    println!("x coordinate: {}", point.0);
}

// Associated functions and methods
impl User {
    // Associated function (similar to static method)
    fn new(email: String, username: String) -> User {
        User {
            email,
            username,
            active: true,
            sign_in_count: 1,
        }
    }

    // Method
    fn is_active(&self) -> bool {
        self.active
    }

    fn deactivate(&mut self) {
        self.active = false;
    }

    fn activate(&mut self) {
        self.active = true;
        self.sign_in_count += 1;
    }
}

fn struct_methods() {
    // Use associated function
    let mut user = User::new(
        String::from("test@example.com"),
        String::from("testuser")
    );

    println!("User active status: {}", user.is_active());

    user.deactivate();
    println!("Status after deactivation: {}", user.is_active());

    user.activate();
    println!("Status after activation: {}, login count: {}", user.is_active(), user.sign_in_count);
}

🎯 Enums and Matching

Enum Definition

rust
#[derive(Debug)]
enum IpAddrKind {
    V4,
    V6,
}

#[derive(Debug)]
enum IpAddr {
    V4(u8, u8, u8, u8),
    V6(String),
}

#[derive(Debug)]
enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(i32, i32, i32),
}

fn enum_examples() {
    // Basic enum
    let four = IpAddrKind::V4;
    let six = IpAddrKind::V6;

    println!("IP versions: {:?}, {:?}", four, six);

    // Enum with data
    let home = IpAddr::V4(127, 0, 0, 1);
    let loopback = IpAddr::V6(String::from("::1"));

    println!("IP addresses: {:?}, {:?}", home, loopback);

    // Complex enum
    let messages = vec![
        Message::Quit,
        Message::Move { x: 10, y: 20 },
        Message::Write(String::from("Hello")),
        Message::ChangeColor(255, 0, 0),
    ];

    for msg in messages {
        process_message(msg);
    }
}

fn process_message(msg: Message) {
    match msg {
        Message::Quit => println!("Quit program"),
        Message::Move { x, y } => println!("Move to coordinates ({}, {})", x, y),
        Message::Write(text) => println!("Write text: {}", text),
        Message::ChangeColor(r, g, b) => println!("Change color to RGB({}, {}, {})", r, g, b),
    }
}

Option and Result

rust
fn option_examples() {
    // Option enum
    let some_number = Some(5);
    let some_string = Some("string");
    let absent_number: Option<i32> = None;

    println!("Has value: {:?}, {:?}", some_number, some_string);
    println!("No value: {:?}", absent_number);

    // Handle Option
    match some_number {
        Some(value) => println!("Found value: {}", value),
        None => println!("No value"),
    }

    // Simplified matching with if let
    if let Some(value) = some_number {
        println!("if let found value: {}", value);
    }

    // unwrap_or provides default value
    let default_value = absent_number.unwrap_or(0);
    println!("Default value: {}", default_value);
}

fn result_examples() {
    // Result used for error handling
    let good_result: Result<i32, &str> = Ok(10);
    let bad_result: Result<i32, &str> = Err("Error occurred");

    match good_result {
        Ok(value) => println!("Success: {}", value),
        Err(error) => println!("Error: {}", error),
    }

    match bad_result {
        Ok(value) => println!("Success: {}", value),
        Err(error) => println!("Error: {}", error),
    }

    // Chained operations
    let result = divide(10, 2)
        .and_then(|x| divide(x, 2))
        .and_then(|x| divide(x, 0)); // This will error here

    match result {
        Ok(value) => println!("Final result: {}", value),
        Err(error) => println!("Calculation error: {}", error),
    }
}

fn divide(dividend: i32, divisor: i32) -> Result<i32, String> {
    if divisor == 0 {
        Err("Cannot divide by zero".to_string())
    } else {
        Ok(dividend / divisor)
    }
}

🎬 Complete Example: Guessing Game

rust
use std::io;
use std::cmp::Ordering;
use rand::Rng;

fn guessing_game() {
    println!("Guess the number game!");

    let secret_number = rand::thread_rng().gen_range(1..101);

    loop {
        println!("Please enter your guess (1-100):");

        let mut guess = String::new();

        io::stdin()
            .read_line(&mut guess)
            .expect("Failed to read input");

        let guess: u32 = match guess.trim().parse() {
            Ok(num) => num,
            Err(_) => {
                println!("Please enter a valid number!");
                continue;
            }
        };

        println!("Your guess is: {}", guess);

        match guess.cmp(&secret_number) {
            Ordering::Less => println!("Too small!"),
            Ordering::Greater => println!("Too big!"),
            Ordering::Equal => {
                println!("Congratulations, you guessed correctly!");
                break;
            }
        }
    }
}

fn main() {
    // Run all examples
    println!("=== Data Type Examples ===");
    number_types();
    bool_and_char();
    compound_types();

    println!("\n=== Condition and Loop Examples ===");
    conditionals();
    loops();

    println!("\n=== Ownership Examples ===");
    ownership_basics();
    ownership_functions();
    references_and_borrowing();

    println!("\n=== Struct Examples ===");
    struct_examples();
    struct_methods();

    println!("\n=== Enum Examples ===");
    enum_examples();
    option_examples();
    result_examples();

    println!("\n=== Guessing Game ===");
    guessing_game();
}

📝 Chapter Summary

By studying this chapter, you should have mastered:

Rust Basics

  • ✅ Variables, constants, and basic data types
  • ✅ Function definition and calling
  • ✅ Control flow (conditionals and loops)
  • ✅ Basic concepts of ownership, borrowing, and references

Core Features

  • ✅ Defining and using structs
  • ✅ Enums and pattern matching
  • ✅ Option and Result types
  • ✅ Basic error handling

Practical Experience

  • ✅ Complete project example
  • ✅ Common programming patterns
  • ✅ Rust-specific programming mindset

Continue Learning: Next Chapter - Rust Basic Syntax

Content is for learning and research only.