Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Rust convert iterator over String to &[&str]

How do I convert an iterator that returns Strings to something that I can pass into a function that takes &[&str]? I’m trying to map the iterator to an iterator over &strs, but I get an error:

error[E0515]: cannot return reference to function parameter `s`
  --> src/main.rs:89:52
   |
89 |     let args: Vec<&str> = std::env::args().map(|s| s.as_str()).collect();
   |                                                    ^^^^^^^^^^ returns a reference to data owned by the current function

Why does this error occur? args is a local variable in main so surely its lifetime extends to the end of the function and is therefore alive throughout the entire parse_args call.

If the function should take a different type I can change it, but I’m under the impression that this type is correct for my purposes – I don’t need owned access to a vector, nor owned access to the values.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Here’s the code that reproduces the error:

fn main() {
    let args: Vec<&str> = std::env::args().map(|s| s.as_str()).collect();
    let config = parse_args(&args);
    // do stuff with config
}


fn parse_args(args: &[&str]) {
// parse args
}

>Solution :

You need to collect() twice, first into Vec<String> then iterate over that and collect() it into Vec<&str>:

let args: Vec<String> = std::env::args().collect();
let args: Vec<&str> = args.iter().map(|v| v.as_str()).collect();

let config = parse_args(&args);

This is because std::env::args() returns an iterator over Strings. If you convert them to &strs, they are dropped when we call the next item, and dang! your &str is dangling.

So we need somewhere to store the Strings, and then since we need &[&str] and not &[String], we need to iterate over this and collect it again.

Note however, that it is perfectly fine and normal to take &[String]. Unlike &String, which is basically useless&str is always more flexible, this is not true behind an indirection, such as &[String] vs &[&str], precisely because of what we saw now.

If you want to be maximally permissive (for example, for a public function), you can take &[impl AsRef<str>]. This will allow both. Then when you use the data, you need to convert it to &str using as_ref().

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading