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