
หนึ่งในแนวคิดที่โดดเด่นที่สุดของภาษา 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