
หนึ่งในแนวคิดที่โดดเด่นที่สุดของภาษา Rust คือระบบ Ownership ซึ่งช่วยให้โปรแกรมของเราปลอดภัยจากปัญหาหน่วยความจำ เช่น null pointer, dangling pointer, double free ได้อย่างมีประสิทธิภาพ โดยไม่ต้องพึ่ง Garbage Collector
1. Ownership คืออะไร?
ทุกค่าใน Rust มีเจ้าของ (owner) และจะมีเจ้าของได้เพียงตัวเดียวในแต่ละเวลา
fn main() { let s = String::from("hello"); // s เป็น owner ของ string นี้ takes_ownership(s); // s ถูกย้ายไปที่ฟังก์ชัน // println!("{}", s); // ❌ error เพราะ s ถูกย้ายแล้ว } fn takes_ownership(s: String) { println!("{}", s); }
ผลลัพธ์:
“hello” แสดงผลได้ในฟังก์ชัน takes_ownership
เท่านั้น เพราะ ownership ถูกย้าย (move)
2. Borrowing คืออะไร?
แทนที่จะย้าย ownership เราสามารถ “ยืม” (borrow) ค่านั้นมาใช้งานชั่วคราวได้
fn main() { let s = String::from("hello"); print_str(&s); // ยืมแบบ immutable borrow println!("{}", s); // ✅ ใช้ได้ เพราะ s ยังเป็นเจ้าของ } fn print_str(s: &String) { println!("{}", s); }
กฎของ Borrowing
- คุณสามารถยืมได้หลายแบบ
&T
(immutable) - แต่ถ้ามีการยืมแบบ
&mut T
(mutable) จะต้องมีแค่ตัวเดียว - การ borrow แบบ immutable และ mutable พร้อมกันไม่ได้
fn main() { let mut s = String::from("hello"); let r1 = &s; // ✅ ok let r2 = &s; // ✅ ok // let r3 = &mut s; // ❌ error: cannot borrow `s` as mutable println!("{} {}", r1, r2); }
3. Lifetimes คืออะไร?
Lifetimes คือการบอกว่า reference ตัวใดจะมีอายุการใช้งานได้นานแค่ไหน เพื่อป้องกัน dangling reference
ตัวอย่างปัญหา:
fn main() { let r; { let x = 5; r = &x; // ❌ error: `x` จะหมดอายุใน block นี้ } println!("{}", r); }
แก้โดยใช้ explicit lifetime:
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { if x.len() > y.len() { x } else { y } }
4. ทำไม Rust ต้องมีระบบนี้?
- ป้องกันการเข้าถึง memory ที่หมดอายุ
- ไม่ต้องพึ่ง GC แต่ยังปลอดภัย
- ทำให้ compile-time ตรวจจับ bug ได้มากขึ้น
- ลดความซับซ้อนของ runtime
5. แนวทางการเขียนที่ดี
- ใช้
&
(immutable borrow) ให้มากที่สุด - หลีกเลี่ยง
&mut
เมื่อไม่จำเป็น - อย่าส่งค่ากลับจากฟังก์ชันด้วย reference ของ local var
- ใช้
Clone
หรือto_owned()
หากต้อง copy data
6. Bonus: Copy vs Move
fn main() { let x = 5; let y = x; // ✅ OK เพราะ i32 เป็น Copy println!("{} {}", x, y); let s1 = String::from("hi"); let s2 = s1; // ❌ s1 ถูก move ไปที่ s2 // println!("{}", s1); // error }
7. แหล่งเรียนรู้เพิ่มเติม
- Rust Book: Chapter 4
- Clippy สำหรับแนะนำ code style
- Rustlings แบบฝึกหัดการเรียน Ownership/Borrowing
สรุป
Ownership, Borrowing, และ Lifetimes คือหัวใจของความปลอดภัยในภาษา Rust
แม้จะดูยากในตอนแรก แต่เมื่อเข้าใจแล้วคุณจะได้ภาษาโปรแกรมที่ “เร็ว ปลอดภัย และไม่พัง” ได้อย่างมั่นใจ
📌 คำค้น SEO
Ownership Rust, Borrowing Rust, Lifetime Rust, เข้าใจ Ownership Rust, Rust memory safety, Rust ย้ายค่า, Rust ยืมค่าชั่วคราว, Lifetimes Rust ภาษาไทย, Rust ไม่ต้อง GC, Rust reference ปลอดภัย
เผยแพร่โดย poolsawat.com