I'm working through the Rust book, and it has the following example of how to use the filter
method on Iterator
s (source):
struct Shoe {
size: u32,
style: String,
}
fn shoes_in_my_size(shoes: Vec<Shoe>, shoe_size: u32) -> Vec<Shoe> {
shoes.into_iter().filter(|s| s.size == shoe_size).collect()
}
I started thinking of how I could improve this function with the following objectives:
- Do not consume/take ownership the
shoes
vector, so the caller can still use it. - Return a vector of just the
style
s, rather than of the wholeShoe
struct.
I came up with the following two possible solutions:
fn shoe_styles_in_my_size(shoes: &[Shoe], shoe_size: u32) -> Vec<&String> {
shoes
.iter()
.filter(|s| s.size == shoe_size)
.map(|s| &s.style)
.collect()
}
and:
fn shoe_styles_in_my_size(shoes: &[Shoe], shoe_size: u32) -> Vec<&str> {
shoes
.iter()
.filter(|s| s.size == shoe_size)
.map(|s| &s.style[..])
.collect()
}
The difference being that the first example returns Vec<&String>
and the second returns Vec<&str>
.
What criteria would I use to determine which of these two is "better?" I've been under the impression that using str
is preferable to using String
when possible, since it is more flexible (hopefully this is accurate?) Is there any overhead associated with the [..]
operation? My understanding says no, but I'm not sure.