Ownership
JavaScript manages memory for you — Rust does not
Section titled “JavaScript manages memory for you — Rust does not”In JavaScript and TypeScript, every heap value (strings, arrays, objects) is tracked by a garbage collector. You create values freely; the GC figures out when nobody is using them and frees the memory. You never call free(). You never worry about use-after-free.
Rust has no garbage collector. Instead it has ownership: a compile-time system of rules that gives every value exactly one owner. When the owner goes out of scope, the value is automatically freed — no GC needed.
Moving ownership
Section titled “Moving ownership”In TypeScript, assigning an object to a new variable creates a second reference. Both variables point to the same data. In Rust, assigning a heap value moves ownership: the original variable is invalidated.
// TypeScript — two references, same objectconst a = { name: "Alice" };const b = a; // b points to the same objectconsole.log(a.name); // "Alice" — a is still validconsole.log(b.name); // "Alice" — both work
// The GC will free the object when BOTH a and b go out of scope.// You cannot control when.fn main() { // Rust — String is a heap value let a = String::from("Alice"); let b = a; // ownership MOVES from a to b // println!("{}", a); // error[E0382]: use of moved value: `a` println!("{}", b); // only b is valid now
// When b goes out of scope at the end of main(), // Rust automatically frees the String data. No GC needed.}Ownership through functions
Section titled “Ownership through functions”Passing a heap value to a function moves it into that function. The caller can no longer use it unless the function returns it back.
// TypeScript — passing an object does not move ownershipfunction greet(name: string) { console.log(`Hello, ${name}`);}
const s = "world";greet(s);console.log(s); // still valid — JS passes by reference for objectsfn greet(name: String) { // name is owned here println!("Hello, {}", name);} // name is dropped here
fn main() { let s = String::from("world"); greet(s); // ownership moves into greet() // println!("{}", s); // error[E0382]: use of moved value: `s`}Try it
Section titled “Try it”fn takes_ownership(s: String) { println!("got: {}", s);} // s dropped here
fn makes_copy(n: i32) { println!("copy: {}", n);} // n dropped here, but i32 is Copy so the caller's copy is unaffected
fn main() { let s = String::from("hello"); takes_ownership(s); // println!("{}", s); // would be a compile error — s was moved
let x = 5; makes_copy(x); println!("x is still valid: {}", x); // fine — i32 is Copy}Compiling…