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)) }