fn main() {
let s1 = String::from("hello");
let s2 = s1;
println!("{}", s2);
}In Rust, when you assign s1 to s2, ownership moves to s2. Using s1 after that would cause a compile error. Here, only s2 is used in println!, so it prints "hello".
Rust enforces ownership rules at compile time to guarantee memory safety and prevent bugs like dangling pointers or data races, all without needing a garbage collector or manual freeing.
fn main() {
let s = String::from("hello");
let r1 = &s;
let r2 = &mut s;
println!("{} and {}", r1, r2);
}Rust enforces that you cannot have a mutable reference while immutable references exist to the same data. This code tries to do both, so it causes a compile-time error.
fn takes_ownership(some_string: String) { println!("{}", some_string); } fn main() { let s = String::from("hello"); takes_ownership(s); println!("{}", s); }
The function takes_ownership takes ownership of the String. After calling it, s is no longer valid in main, so the second println! causes a compile-time error.
Rust's ownership and borrowing rules ensure that either one mutable reference or many immutable references exist at a time. This prevents data races by design, as conflicting accesses cannot compile.
