Instead of transferring ownership, you can borrow a value using references.
&T)fn calculate_length(s: &String) -> usize {
s.len()
} // s goes out of scope, but since it doesn't own the String, nothing is dropped
let s1 = String::from("hello");
let len = calculate_length(&s1);
println!("{s1} has length {len}"); // s1 is still valid
You can have multiple immutable references at the same time.
&mut T)fn push_world(s: &mut String) {
s.push_str(" world");
}
let mut s = String::from("hello");
push_world(&mut s);
println!("{s}"); // "hello world"
&T or one &mut T β never both at the same timeThis is how Rust prevents data races at compile time β no runtime locks needed.
let s = String::from("hello world");
let hello: &str = &s[0..5];
let world: &str = &s[6..11];
println!("{hello} {world}");
Slices borrow a portion of data without copying.