[Avg. reading time: 3 minutes]
Owner Borrower Stack Heap
fn main() { let o = String::from("Rachel Green"); println!("o (String owner): {o}"); println!("o.len (bytes): {}", o.len()); println!("o.capacity (bytes): {}", o.capacity()); // stack vs heap println!("\nstack addr of o (String struct): {:p}", &o); println!("heap ptr held by o: {:p}", o.as_ptr()); // slice: &str borrows part of o (points into the same heap buffer) let s: &str = &o[7..]; // "Green" for ASCII input println!("\ns (&str slice): {s}"); println!("stack addr of s (&str ref): {:p}", &s); println!("ptr of s (into o's buffer): {:p}", s.as_ptr()); // borrow: &String (borrow the whole String) let b: &String = &o; println!("\nb (&String borrow): {b}"); println!("stack addr of b (&String ref): {:p}", &b); println!("b points to String struct o: {:p}", b as *const String); println!("b -> heap ptr: {:p}", b.as_ptr()); // Key takeaway println!("\nCheck: o.as_ptr == s.as_ptr ? {}", o.as_ptr() == s.as_ptr()); println!("Check: o.as_ptr == b.as_ptr ? {}", o.as_ptr() == b.as_ptr()); let moved = o; // println!("{}", o); // error: moved println!("{}", moved); }