1

If I try to run this:

use std::{fs, process};

fn read_file_to_vec(file_path: &str) -> Vec<&str> {
    let file_string = match fs::read_to_string(file_path) {
        Ok(a) => a,
        Err(e) => {
            eprintln!("{}", e);
            process::exit(2)
        }
    };
    file_string.split("\n").collect::<Vec<&str>>()
}

fn main() {
    read_file_to_vec("/home/john/passwords.txt");
}

I get:

error[E0515]: cannot return value referencing local variable `file_string`
  --> src/main.rs:11:5
   |
11 |     file_string.split("\n").collect::<Vec<&str>>()
   |     -----------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |     |
   |     returns a value referencing data owned by the current function
   |     `file_string` is borrowed here

Why can I not return a vector that consumed the file_string variable already? What should I do to move file_string into the vector?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
scagbackbone
  • 681
  • 1
  • 8
  • 20
  • *that consumed the `file_string` variable* — it did not. `split` returns references to the value being split on. Use `file_string.split("\n").map(String::from).collect()` instead. – Shepmaster Oct 26 '20 at 16:58
  • That would cause return value to be Vec and I would like to keep Vec<&str> – scagbackbone Oct 26 '20 at 17:04
  • That's impossible as currently asked. When the function exits, `file_string` is dropped, invalidating the references. That's thoroughly explained in the duplicates. See alse [How can I store a Chars iterator in the same struct as the String it is iterating on?](https://stackoverflow.com/q/43952104/155423); [Is there an owned version of String::chars?](https://stackoverflow.com/q/47193584/155423); [Why can't I store a value and a reference to that value in the same struct?](https://stackoverflow.com/q/32300132/155423). – Shepmaster Oct 26 '20 at 17:17
  • 2
    To have `Vec<&str>` you must have some `String` which will be the backing storage for every `&str`. References can't exist on their own. – Cerberus Oct 26 '20 at 17:17
  • @Cerberus does it need to be `String`? Can it be backed just by str allocated in read only memory --> `let x = "rust"` or `let x: &'static str = "rust" ` ?? – scagbackbone Oct 27 '20 at 12:17
  • Well, not necessarily `String`. Of course, you can use `&'static str` with string literals for everything known at compile-time and references given by `Box::leak` otherwise. – Cerberus Oct 27 '20 at 13:15

0 Answers0