4

I use to have extensive use of Vec<&str>, but someone on Discord talked me into changing that to &[&str], however in some cases this has produced problems. Take for example this code which used to work,

fn main() { let pos: Vec<String> = vec!["foo".to_owned(), "bar".to_owned(), "baz".to_owned()]; let pos: Vec<&str> = pos.iter().map(AsRef::as_ref).collect(); } 

When I change that second line to

let pos: &[&str] = pos.iter().map(AsRef::as_ref).collect(); 

I get the error,

error[E0277]: a value of type `&[&str]` cannot be built from an iterator over elements of type `&_` --> bin/seq.rs:3:51 | 3 | let pos: &[&str] = pos.iter().map(AsRef::as_ref).collect(); | ^^^^^^^ value of type `&[&str]` cannot be built from `std::iter::Iterator<Item=&_>` | = help: the trait `FromIterator<&_>` is not implemented for `&[&str]` 

How can I convert a Vec<String> into a &[&str]. I got this method from this answer on StackOverflow, which I tried to port to &[&str] with no luck.

8
  • Have you tried? let pos:&[&str] = &pos.iter().map(AsRef::as_ref).collect::<Vec<_>>()[..] Commented Oct 12, 2021 at 6:22
  • you can trivially use a &Vec<T> as a &[T], there's a deref-coercion for it, but you need to .collect() into a Vec. Commented Oct 12, 2021 at 6:22
  • 1
    The advice you received sounds like it was either given or taken haphazardly, perhaps the reasoning was similar to this? Why is it discouraged to accept a reference to a String (&String), Vec (&Vec), or Box (&Box) as a function argument? Commented Oct 12, 2021 at 6:27
  • @kmdreko If I try collecting into a vec and passing that in I get the trait From<&Vec<&str>> is not implemented for PositionalArgs<'_> Commented Oct 12, 2021 at 6:36
  • 1
    Please check the as_slice, it does the same thing(playground). And for the github issue, please be careful, that code is not correct, you are missing & while getting slice Commented Oct 12, 2021 at 7:22

1 Answer 1

6

A simple way is to use .as_slice()

let pos: Vec<String> = vec!["foo".to_owned(), "bar".to_owned(), "baz".to_owned()]; let pos: Vec<&str> = pos.iter().map(AsRef::as_ref).collect(); let pos: &[&str] = pos.as_slice(); 

But, perhaps a better solution exist


Sign up to request clarification or add additional context in comments.

2 Comments

Great answer thanks a ton! If someone has a better answer, I'll accept it instead, but this is working for me.
Juste about the alternative proposition in github, "let pos: &[&str] = pos.iter().map(AsRef::as_ref).collect::<Vec<_>>().as_slice();". This compile but not work. If you try to use pos it, i.e. "dbg!(pos)", get "error[E0716]: temporary value dropped while borrowed".

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.