Challenge 3: Returning Ownership Back — Possible Solution ==================================================================== fn print_and_return(s: String) -> String { println!("{}", s); s } fn main() { let s = String::from("hello"); let s = print_and_return(s); println!("still usable: {}", s); } WHY THIS WORKS AS AN ANSWER ------------------------------ Calling print_and_return(s) MOVES ownership of the String into the function, exactly as this chapter's takes_ownership example demonstrated — inside the function, the parameter s is now the sole owner of that data. The key difference from this chapter's original example: instead of letting the function's scope end (which would drop s and free its memory), print_and_return explicitly RETURNS s as its last expression (no semicolon — the expression-as-return-value rule from Chapter 2's warn-box). This transfers ownership back OUT of the function to whatever called it. Back in main, let s = print_and_return(s) shadows the original s with this returned value — the caller now owns a String again (technically a NEW binding, per Chapter 2's shadowing, though it holds the exact same data that was originally moved in), and it remains fully usable in the following println!, all without ever calling .clone() — the data was moved out and then moved back, never duplicated.