Chapter 5. Why It’s Discouraged to Accept a Reference to a String, Vec, or Box as a Function Parameter
Here’s some Rust code that takes a &String as a parameter:
fn awesome_greeting(name: &String) {
println!("Wow, you are awesome, {}!", name);
}
And here’s code that takes a reference to a Vec:
fn total_price(prices: &Vec) -> i32 {
prices.iter().sum()
}
And code that takes a reference to a Box:
fn is_even(value: &Box) -> bool {
**value % 2 == 0
}
These function definitions work, but they’re not idiomatic Rust. The reason is that we can instead define functions to use &str, &[T] or &T as parameter types with no loss of genericity. Let’s explore further.
One of the main reasons to use a String or a Vec is because they allow increasing or decreasing the capacity. However, when we use an immutable reference as a parameter type in a function definition, that function can’t use any of those interesting methods on the Vec or String.
Accepting a &String, &Vec or &Box also requires an allocation before we can call the method. Unnecessary allocation is a performance loss. This is usually exposed right away when we try to call these methods in a test or a main method:
fn main() {
awesome_greeting(&String;:from("Anna"));
total_price(&vec![42, 13, 1337])
is_even(&Box;:new(42))
}