Memory Safety โดยไม่ต้องใช้ Garbage Collector: เจาะลึก Ownership

Sharing is caring!

หนึ่งในจุดแข็งของ Rust คือความสามารถในการจัดการหน่วยความจำอย่างปลอดภัย โดยไม่ต้องพึ่งพา Garbage Collector ระบบ Ownership ใน Rust เป็นกลไกสำคัญที่ทำให้ Rust ปลอดภัยและมีประสิทธิภาพสูง ทั้งในงานฝั่ง embedded, system-level, และ web assembly

1. Ownership คืออะไร?

ใน Rust ทุกค่า (value) จะมี owner และมีได้แค่หนึ่งเดียวในเวลาใดเวลาหนึ่ง เมื่อ owner หลุด scope ค่าในหน่วยความจำนั้นจะถูก drop อัตโนมัติ

fn main() {
    let s = String::from("hello"); // s เป็นเจ้าของ
    println!("{}", s); // ใช้ได้ปกติ
} // s หลุด scope และ memory จะถูกคืนโดยอัตโนมัติ

2. Move Semantics

เมื่อค่าถูกส่งไปยังฟังก์ชันหรือผันผ่านตัวแปร มันจะเกิดการ “move”

fn main() {
    let s1 = String::from("rust");
    let s2 = s1; // s1 ถูก move ไปยัง s2
    // println!("{}", s1); ❌ compile error: s1 ไม่สามารถใช้งานได้อีก
}

3. Borrowing และการอ้างอิง (&)

แทนที่จะ move เราสามารถ “ยืม” ตัวแปรได้ผ่าน reference

Borrow แบบ immutable

fn print_length(s: &String) {
    println!("Length: {}", s.len());
}

fn main() {
    let s = String::from("hello");
    print_length(&s); // ยืมแบบไม่เปลี่ยนแปลง
}

Borrow แบบ mutable

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

fn main() {
    let mut s = String::from("hello");
    change(&mut s);
    println!("{}", s); // hello world
}

4. Borrow Checker ทำงานอย่างไร?

Borrow Checker ตรวจสอบว่าไม่มีการ borrow แบบ mutable และ immutable พร้อมกัน รวมถึงห้ามมีการใช้หลังจาก move

5. Lifetimes: ทำให้ borrow ปลอดภัย

เมื่อ borrow ค่าข้าม scope Rust ต้องการให้เรากำหนด lifetime เพื่อให้แน่ใจว่า reference นั้นจะไม่กลายเป็น dangling

fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() { x } else { y }
}

6. ไม่มี Garbage Collector แต่ปลอดภัย

  • ไม่มีการ pause หรือ stop-the-world
  • สามารถจัดการ memory ได้เทียบเท่า C/C++
  • ไม่มี double free, use-after-free
  • ระบบ type + borrow checker = safety without runtime cost

7. Drop Trait และการ clean up

คุณสามารถ implement Drop เพื่อกำหนดสิ่งที่จะทำเมื่อค่าออกจาก scope

struct Connection;
impl Drop for Connection {
    fn drop(&mut self) {
        println!("Closing connection");
    }
}

ภาพประกอบ Ownership

บทสรุป

ระบบ Ownership ของ Rust ทำให้เราสามารถเขียนโค้ดที่ปลอดภัยด้าน memory โดยไม่ต้องใช้ garbage collector ไม่ต้องกังวลเรื่อง memory leak หรือ race condition จาก shared state แบบเดิม ๆ อีกต่อไป หากเข้าใจพื้นฐานนี้ จะสามารถเขียนระบบขนาดใหญ่และซับซ้อนได้อย่างมั่นใจ

บทความโดย poolsawat.com – ความรู้ Rust สำหรับ Dev ยุคใหม่ที่ใส่ใจความปลอดภัยของระบบ

Leave a Reply

อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *