ข้ามไปยังเนื้อหา

Rust ที่ไม่มีใน TypeScript

TypeScript เป็นภาษาที่ดีมาก แต่ทำงานบน JavaScript runtime ที่มี garbage collector (GC) และ runtime ตัวนั้นตัดสินใจหลายอย่างแทนเรา: memory จะถูกคืนเมื่อไหร่? ใครเป็นเจ้าของ value นั้น? thread สองตัวอ่าน object เดียวกันพร้อมกันได้ไหม?

Rust ทำให้การตัดสินใจเหล่านี้ explicit — ตั้งแต่ compile time และไม่มีต้นทุน runtime เลย ผลคือ Rust มี concept บางอย่างที่ ไม่มีใน TypeScript เลย และ module นี้จะพาไปดูให้ครบ

ใน TypeScript (และ JavaScript) คุณไม่เคยต้องคิดเรื่อง memory เลย:

TypeScript
// TypeScript — memory มองไม่เห็น
const greeting = "hello"; // allocated บน heap ที่ไหนสักที่
const copy = greeting; // ทั้งคู่ชี้ไปที่ string object เดียวกัน
// "hello" จะถูกคืนเมื่อไหร่? GC ตัดสินใจ คุณไม่มีทางรู้
// ไม่มี ownership ไม่มีกฎ มีแค่ references
function process(s: string) {
console.log(s);
}
process(greeting);
console.log(greeting); // ยังใช้ได้ — GC ยังคงมันไว้
Rust
fn main() {
// Rust — ownership ชัดเจน
let s = String::from("hello"); // s เป็น owner ของ string data
let t = s; // ownership MOVES ไปที่ t; s หมดแล้ว
// println!("{}", s); // compile error: s ถูก move แล้ว
println!("{}", t); // ใช้ได้แค่ t
// borrowing — เข้าถึงชั่วคราวโดยไม่ move
let greeting = String::from("world");
let len = calc_len(&greeting); // ยืม greeting; เราเก็บ ownership ไว้
println!("{} has {} chars", greeting, len);
// Copy type — i32 copy ถูกมากจึง copy อัตโนมัติ
let x: i32 = 42;
let y = x; // x ไม่ถูก moved — มันถูก copied
println!("x={} y={}", x, y); // ทั้งคู่ใช้ได้
}
fn calc_len(s: &String) -> usize {
s.len()
}
fn main() {
// move semantics
let s = String::from("hello");
let t = s; // s is moved into t
println!("{}", t); // only t is valid
// borrowing
let greeting = String::from("world");
let len = calc_len(&greeting);
println!("{} has {} chars", greeting, len);
// Copy type
let x: i32 = 42;
let y = x; // i32 is Copy — both x and y are valid
println!("x={} y={}", x, y);
}
fn calc_len(s: &String) -> usize {
s.len()
}
อะไรที่ถูกจัดการโดย Rust compiler — ไม่ใช่ runtime?
เกิดอะไรขึ้นกับ `s` หลังจาก `let t = s;` เมื่อ `s` เป็น `String`?
ทำไม TypeScript ถึงไม่ต้องการกฎ ownership?