// Borrowing data // // We can access data created in another scope by borrowing it. // // Can be borrowed mutable or immutable. // // Borrowing Rules: // // - At any given time, you can have either a // SINGLE MUTABLE reference or // MANY IMMUTABLE references // - References must always be valid // // We can define references by // // Passing the reference to a var: let x = &var // Using the ref keyworkd like: let ref x = var fn main() { let s1 = String::from("hello"); // Pass a reference to String s1 // this is a reference to the s1 not the string per se let len: usize = calculate_length(& s1); // Mutable ref let mut c = String::from("Howdy"); // Pass a mutable reference to change function change(&mut c); // We can still use s1 here, because s1 is still the owner. println!("The length of '{}' is {}.", s1, len); println!("{}", c); print_pointer(); } // The function receives a 'reference' to a String fn calculate_length(s: & String) -> usize { return s.len(); } fn change(c: &mut String) { c.push_str(" partner"); } fn print_pointer() { let x: i32 = 5; let p: &i32 = &x; println!("PTR is: {:p}", p); } // This function is just an example of 2nd rule violation // It returns a reference to a string that will run out of // scope once the function returns. // Thanks to that, we return a dangling pointer. Rustc won't // let us compile it. // Could be fixed by returning the String data itself //fn dangling_ptr() -> &String { // let s = String::from("howdy"); // // return &s; //}