I'm walking through Microsoft's Rust tutorial here, which is about
implement the
copy_and_returnfunction so that it returns a reference to the value inserted in the vector
Solution is given here, but it's different from mine in that it used &String as return type while I used &str.
// standard solution
fn copy_and_return<'a>(vector: &'a mut Vec<String>, value: &'a str) -> &'a String {
vector.push(String::from(value));
vector.get(vector.len() - 1).unwrap()
}
// my solution
fn copy_and_return<'a>(vector: &'a mut Vec<String>, value: &'a str) -> &'a str {
vector.push(String::from(value));
return value; // simply return value
}
fn main() {
let name1 = "Joe";
let name2 = "Chris";
let name3 = "Anne";
let mut names = Vec::new();
assert_eq!("Joe", copy_and_return(&mut names, &name1));
assert_eq!("Chris", copy_and_return(&mut names, &name2));
assert_eq!("Anne", copy_and_return(&mut names, &name3));
assert_eq!(
names,
vec!["Joe".to_string(), "Chris".to_string(), "Anne".to_string()]
)
}
In addition to the return type, another difference between mine and the standard solution is that I simply returned the parameter value, while the standard solution used complicated way vector.get(vector.len() - 1).unwrap().
I'm wondering if there's anything wrong with my solution that the tutorial takes another way?
While @Masklinn provided a great answer to my question, it's a bit specific to the example I gave but not directly addressing the title What is the difference between &str and &String.
I found this discussion to be quite informative:
Basically a
Stringwraps and manages a dynamically allocated str as backing storage. Since str cannot be resized, String will dynamically allocate/deallocate memory. A&stris thus a reference directly into the backing storage of the String, while &String is a reference to the “wrapper” object. Additionaly, &str can be used for substrings, i.e. they are slices. A &String references always the whole string.
Chapter 4.3 of the Rust book also helps