Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Rust Cheatsheet

สรุปคำสั่งและ syntax ที่ใช้บ่อยใน Rust


Variables

// Immutable (ค่าคงที่)
let x = 5;

// Mutable (เปลี่ยนค่าได้)
let mut y = 10;
y = 20;

// Type annotation
let z: i32 = 100;

// Constants (ต้องระบุ type)
const MAX_POINTS: u32 = 100_000;

// Shadowing
let x = 5;
let x = x + 1; // x = 6

Data Types

Scalar Types

Typeตัวอย่าง
i8, i16, i32, i64, i128-128, 42
u8, u16, u32, u64, u1280, 255
f32, f643.14, 2.0
booltrue, false
char'a', '🦀'

Compound Types

// Tuple
let tup: (i32, f64, bool) = (500, 6.4, true);
let (x, y, z) = tup;  // destructuring
let first = tup.0;     // indexing

// Array (fixed size)
let arr: [i32; 5] = [1, 2, 3, 4, 5];
let first = arr[0];
let arr = [3; 5]; // [3, 3, 3, 3, 3]

Functions

// Basic function
fn greet() {
    println!("Hello!");
}

// With parameters
fn greet_name(name: &str) {
    println!("Hello, {}!", name);
}

// With return value
fn add(a: i32, b: i32) -> i32 {
    a + b  // no semicolon = return
}

// Early return
fn check(x: i32) -> bool {
    if x > 10 {
        return true;
    }
    false
}

Control Flow

If/Else

if x > 5 {
    println!("Big");
} else if x > 0 {
    println!("Small");
} else {
    println!("Zero or negative");
}

// As expression
let result = if x > 5 { "big" } else { "small" };

Loops

// Infinite loop
loop {
    break;  // exit
}

// While loop
while x > 0 {
    x -= 1;
}

// For loop
for i in 0..5 {
    println!("{}", i);  // 0, 1, 2, 3, 4
}

for item in &vec {
    println!("{}", item);
}

Ownership

// Move
let s1 = String::from("hello");
let s2 = s1;  // s1 is invalid now

// Clone (deep copy)
let s1 = String::from("hello");
let s2 = s1.clone();  // s1 still valid

// Reference (borrow)
let s1 = String::from("hello");
let len = calculate_length(&s1);  // s1 still valid

// Mutable reference
fn change(s: &mut String) {
    s.push_str(" world");
}

Structs

// Define
struct User {
    username: String,
    email: String,
    active: bool,
}

// Create
let user = User {
    username: String::from("john"),
    email: String::from("john@example.com"),
    active: true,
};

// Methods
impl User {
    fn new(username: String) -> Self {
        Self {
            username,
            email: String::new(),
            active: true,
        }
    }

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

Enums & Match

// Define
enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
}

// Match
match msg {
    Message::Quit => println!("Quit"),
    Message::Move { x, y } => println!("Move to {}, {}", x, y),
    Message::Write(text) => println!("Write: {}", text),
}

// Option
let x: Option<i32> = Some(5);
let y: Option<i32> = None;

match x {
    Some(value) => println!("{}", value),
    None => println!("No value"),
}

// if let
if let Some(value) = x {
    println!("{}", value);
}

Error Handling

// Result
fn divide(a: f64, b: f64) -> Result<f64, String> {
    if b == 0.0 {
        Err(String::from("Division by zero"))
    } else {
        Ok(a / b)
    }
}

// Handle Result
match divide(10.0, 2.0) {
    Ok(result) => println!("{}", result),
    Err(e) => println!("Error: {}", e),
}

// ? operator
fn read_file() -> Result<String, std::io::Error> {
    let content = std::fs::read_to_string("file.txt")?;
    Ok(content)
}

// unwrap (panic if error)
let content = std::fs::read_to_string("file.txt").unwrap();

// expect (panic with message)
let content = std::fs::read_to_string("file.txt")
    .expect("Failed to read file");

Collections

Vec

let mut v: Vec<i32> = Vec::new();
let v = vec![1, 2, 3];

v.push(4);
v.pop();

let first = &v[0];
let first = v.get(0);  // Option<&i32>

for i in &v {
    println!("{}", i);
}

String

let mut s = String::new();
let s = String::from("hello");
let s = "hello".to_string();

s.push_str(" world");
s.push('!');

let s3 = format!("{} {}", s1, s2);

HashMap

use std::collections::HashMap;

let mut map = HashMap::new();
map.insert("key", "value");

let value = map.get("key");  // Option<&V>

for (key, value) in &map {
    println!("{}: {}", key, value);
}

Iterators

let v = vec![1, 2, 3, 4, 5];

// Common methods
v.iter().map(|x| x * 2);
v.iter().filter(|x| **x > 2);
v.iter().sum::<i32>();
v.iter().collect::<Vec<_>>();
v.iter().for_each(|x| println!("{}", x));
v.iter().find(|x| **x == 3);
v.iter().any(|x| *x > 2);
v.iter().all(|x| *x > 0);

Smart Pointers

// Box - Heap allocation
let b = Box::new(5);

// Rc - Reference counting
use std::rc::Rc;
let a = Rc::new(5);
let b = Rc::clone(&a);

// RefCell - Interior mutability
use std::cell::RefCell;
let data = RefCell::new(5);
*data.borrow_mut() += 1;

Traits

// Define
trait Summary {
    fn summarize(&self) -> String;

    // Default implementation
    fn default_summary(&self) -> String {
        String::from("...")
    }
}

// Implement
impl Summary for Article {
    fn summarize(&self) -> String {
        format!("{} by {}", self.title, self.author)
    }
}

// Trait bounds
fn notify<T: Summary>(item: &T) {
    println!("{}", item.summarize());
}

// where clause
fn notify<T>(item: &T)
where
    T: Summary + Clone,
{
    println!("{}", item.summarize());
}

Async

// Async function
async fn fetch_data() -> String {
    // ...
    String::from("data")
}

// Await
async fn process() {
    let data = fetch_data().await;
    println!("{}", data);
}

// Tokio main
#[tokio::main]
async fn main() {
    process().await;
}

👉 Cargo Commands