Filtering a Vec of structs and creating new vector of Strings or strs in Rust I'm working through the Rust book, and it has the following example of how to use the filter method on Iterators (source):
struct Shoe {
    size: u32,
    style: String,
}

fn shoes_in_my_size(shoes: Vec&lt;Shoe&gt;, shoe_size: u32) -&gt; Vec&lt;Shoe&gt; {
    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 styles, rather than of the whole Shoe struct.

I came up with the following two possible solutions:
fn shoe_styles_in_my_size(shoes: &amp;[Shoe], shoe_size: u32) -&gt; Vec&lt;&amp;String&gt; {
    shoes
        .iter()
        .filter(|s| s.size == shoe_size)
        .map(|s| &amp;s.style)
        .collect()
}

and:
fn shoe_styles_in_my_size(shoes: &amp;[Shoe], shoe_size: u32) -&gt; Vec&lt;&amp;str&gt; {
    shoes
        .iter()
        .filter(|s| s.size == shoe_size)
        .map(|s| &amp;s.style[..])
        .collect()
}

The difference being that the first example returns Vec&lt;&amp;String&gt; and the second returns Vec&lt;&amp;str&gt;.
What criteria would I use to determine which of these two is &quot;better?&quot;  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.
The [..] slicing operation isn't going to cost anything, but isn't very descriptive either. I'd want to call s.style.as_str() instead.
As for the return type, I'd agree that &amp;str is more appropriate, since it is the more general type. The functionality of a String is a superset of what you can do with a str, so it's irrelevant when that extra functionality isn't useful to the caller