Is This the Best Way to Go From Vec<String> to Vec<&str>?

Is this the best way to go from Vec<String> to Vec<&str>?

my_vec.iter().map(AsRef::as_ref).collect()

Seems like a XY problem, why do you have Vec<&'a str> at the first place?

Anyway your snippet wouldn't work, as you can't convert &&str into String using AsRef. .map(|s| s.to_owned()) would work though.

I edited the above because Markdown was taking out my <String>. I'm tryin to go from Vec<String> to Vec<&str>, not the other way around. That does work. I just wanted to make sure that there wasn't an easier way to do it.

I keep needing to do it while I compose things like command arguments. The functions I'm calling take either a Vec<&str> or, more-likely a &[&str], but I need to build the commands where some arguments need to be format!ed and therefore I need owned Strings instead of just string literal &strs. For example:

let args: Vec<String> = vec!["some".into(), "command".into()];

if let Some(value) = hash_map.get("key") {
    args.push(format!("{}={}", key, value));
}

// This takes a `&[&str]`
run_command(args.iter().map(AsRef::as_ref).collect().as_slice())

That last line was just a bit of a mouthful, but it isn't bad if thats the easiest way to do it.

That is probably the simplest way. You need to build a new Vec because you can't simply convert a Vec<String> to Vec<&str> in place, so each of those methods is necessary one way or another.

2 Likes

AsRef should only be used in a generic context. Otherwise, you open yourself up to type inference failures in a future Rust release. Instead, do this:

strings.iter().map(String::as_str).collect()

Or, via deref:

strings.iter().map(|s| &**s).collect()
6 Likes

Thanks. That makes sense.

Ah, OK. I've lately been using the most generic equivalent function that accomplishes the same thing lately because I can use the same thing everywhere. Such as .into() instead of to_string(). Is that in general going to be fine?

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.