ไม่มี Garbage Collector
ทุกภาษาที่คุณรู้จักมี garbage collector — Rust ไม่มี
หัวข้อที่มีชื่อว่า “ทุกภาษาที่คุณรู้จักมี garbage collector — Rust ไม่มี”Node.js, Python, Go, Java, C# — ทุกภาษา mainstream ที่คุณน่าจะเคยเขียนทำงานบน GC GC สแกน memory เป็นระยะ หา object ที่ไม่ถูกใช้แล้ว และคืน memory แบบนี้ปลอดภัยและสะดวก แต่มีต้นทุน:
- Pause latency: GC stop-the-world pause สามารถ spike latency ได้อย่างคาดเดาไม่ได้
- Throughput overhead: งาน GC แข่งกับโปรแกรมของคุณสำหรับ CPU time
- Memory overhead: GC runtime เก็บ data structure พิเศษเพื่อ track live object
- Non-determinism: คุณไม่สามารถทำนายได้ว่า object จะถูกคืนเมื่อไหร่
Rust ไม่มีสิ่งเหล่านี้เลย แต่ได้ memory safety มาจาก ownership model ล้วน ๆ ตัว Compiler พิสูจน์แบบ static ว่า memory ถูกจัดการถูกต้อง แล้ว generate โค้ดคืน allocation แต่ละก้อนในจุดที่ถูกต้องพอดี
”Drop” หน้าตาเป็นอย่างไร
หัวข้อที่มีชื่อว่า “”Drop” หน้าตาเป็นอย่างไร”คุณ implement Drop trait เพื่อ run cleanup logic แบบ custom เมื่อ value หลุด scope — เทียบเท่า destructor ของ Rust:
// TypeScript — ไม่มี deterministic cleanup โดย defaultclass Resource { constructor(private name: string) { console.log(`acquiring: ${name}`); } // ไม่มี guaranteed destructor ต้องใช้ try/finally หรือ 'using' (ES2023) release() { console.log(`releasing: ${this.name}`); }}
function useResource() { const r = new Resource("file handle"); console.log("using resource"); r.release(); // ลืมเรียกได้ง่าย; ไม่ถูกเรียกถ้า exception}useResource();struct Resource { name: String,}
impl Resource { fn new(name: &str) -> Self { println!("acquiring: {}", name); Resource { name: name.to_string() } }}
impl Drop for Resource { fn drop(&mut self) { println!("releasing: {}", self.name); }}
fn main() { println!("start"); { let _r = Resource::new("file handle"); println!("using resource"); } // _r ถูก drop ที่นี่ — drop() ถูกเรียกอัตโนมัติ println!("end — resource already released");}การ cleanup แบบ deterministic กับ non-deterministic
หัวข้อที่มีชื่อว่า “การ cleanup แบบ deterministic กับ non-deterministic”flowchart TD
subgraph TS["TypeScript / Node.js"]
a1["Object created"] --> a2["..."] --> a3["GC runs at some unknown time"] --> a4["memory freed"]
end
subgraph RS["Rust"]
b1["Value created"] --> b2["owner goes out of scope"] --> b3["memory freed IMMEDIATELY"]
end ความแน่นอนนี้คือเหตุผลที่ Rust ถูกใช้สำหรับ OS kernel, game engine, WebAssembly runtime, และ database เมื่อ file handle หรือ network socket ต้องถูกปิดในจุดที่แน่นอน “GC จะจัดการในที่สุด” ไม่ใช่คำตอบที่ยอมรับได้
ลองเขียนเอง
หัวข้อที่มีชื่อว่า “ลองเขียนเอง”struct Resource { name: String,}
impl Resource { fn new(name: &str) -> Self { println!("acquiring: {}", name); Resource { name: name.to_string() } }}
impl Drop for Resource { fn drop(&mut self) { println!("releasing: {}", self.name); }}
fn main() { println!("start"); { let _r = Resource::new("file handle"); println!("using resource"); } println!("end — resource already released");}Compiling…