1 · Values and control flow · 25 MIN
Borrow strings instead of moving them
Borrowing lets a function inspect data without becoming its owner.
Passing a String by value transfers its ownership, so the caller normally cannot use the old binding afterwards. A shared reference borrows the value and leaves ownership with the caller. &str accepts both slices of owned strings and string literals, making it a flexible read-only input. String length counts bytes, whereas chars counts Unicode scalar values; neither directly counts grapheme clusters such as combined emoji. Choose the measurement that matches the product requirement instead of treating every notion of length as identical.
Use &str when ownership and mutation are unnecessary.
Read the example
fn scalar_count(text: &str) -> usize { text.chars().count() }
fn main() {
let name = String::from("café");
println!("{}", scalar_count(&name));
println!("{}", name.len());
println!("{}", name);
}Check the expected output
4 5 café
Your challenge
Write a function borrowing a string and returning whether it is empty after trim, then reuse the owned String afterwards.
Solution cost: O(n) scalar traversal; len reads the stored byte length in O(1). time · Account for collection storage separately from the returned result. space
Common trap
Slicing a string at an arbitrary byte index can panic on a non-character boundary.
Study the project implementation
fn scalar_count(text: &str) -> usize { text.chars().count() }
fn main() {
let name = String::from("café");
println!("{}", scalar_count(&name));
println!("{}", name.len());
println!("{}", name);
}Further reading: Official documentation
Next lesson: Enums and exhaustive decisions →