This is part two of an intro to Rust and its ownership, referencing and borrowing model. Read part one here. Part one showed us that when a variable falls out of scope it is freed from memory. We then looked at who owns variables as they’re passed around int the code.

Referencing

With our knowledge of ownership and passing ownership to subroutines, we come across a new type of problem. What about when we want the parent function to retain the ownership of a variable? One simple solution is we return the initial variable but this gets messy and nasty. For example, the following code example is counter-intuitive.

fn main() {   
   let s1 = String::from("hello");
   let (s2, len) = calculate_length(s1);
   println!("The length of '{}' is {}.", s2, len);
}
fn calculate_length(s: String) -> (String, usize) {
   let length = s.len();
   // return both the string and length
   (s, length)
}

We’re returning the string and the length, but as a result, we need to declare a new variable back in the main function. It is not enough for code to just work, it needs to be readable as well.

Rust allows you to pass a reference to the variable instead. This allows the parent function to keep the scope of the original variable whilst allowing a child function to use it.

fn main() {
   let name = String::from("Matt");
   let len = calculate_length(&name);
   println!("The length of '{}' is {}.", name, len);
}
fn calculate_length(s: &String) -> usize {
   s.len()
}

The clear difference in the code is the use of “&” when passing the variable to the function and in the function definition. The ampersands are called references and they allow us to refer to a value without transferring the ownership of it.

Image for post

The “&name" syntax creates a reference of the value name but it does not own the value, this means when the scope is dropped in calculate_length Rust will not free the memory. In the calculate_length function, you’ll also note the &String type definition, this indicates the value is a reference.

#rust

Rust And Referencing
1.25 GEEK