Защо моята променлива не живее достатъчно дълго?

Имам прост фрагмент от код, който трябва да прочете файл във вектор по редове

use std::io::{self, Read};
use std::fs::File;

fn file_to_vec(filename: &str) -> Result<Vec<&str>, io::Error> {
    let mut file = try!(File::open(filename));
    let mut string = String::new();
    try!(file.read_to_string(&mut string));
    string.replace("\r", "");

    let data: Vec<&str> = string.split('\n').collect();

    Ok(data)
}

fn main() {}

Получавам следната грешка:

error[E0597]: `string` does not live long enough
  --> src/main.rs:10:27
   |
10 |     let data: Vec<&str> = string.split('\n').collect();
   |                           ^^^^^^ does not live long enough
...
13 | }
   | - borrowed value only lives until here
   |
note: borrowed value must be valid for the anonymous lifetime #1 defined on the function body at 4:1...
  --> src/main.rs:4:1
   |
4  | / fn file_to_vec(filename: &str) -> Result<Vec<&str>, io::Error> {
5  | |     let mut file = try!(File::open(filename));
6  | |     let mut string = String::new();
7  | |     try!(file.read_to_string(&mut string));
...  |
12 | |     Ok(data)
13 | | }
   | |_^

Защо продължавам да получавам тази грешка? Как да поправя това? Предполагам, че има нещо общо с метода split.

Бих могъл да върна низа и след това да го разделя на Vec в основната функция, но наистина искам да върна вектор.


person estw272    schedule 22.10.2015    source източник


Отговори (1)


Проблемът е, че string се създава във вашата функция и ще бъде унищожен, когато функцията се върне. Векторът, който искате да върнете, съдържа части от string, но те няма да са валидни извън вашата функция.

Ако не се притеснявате много за производителността, можете да върнете Vec<String> от вашата функция. Просто трябва да върнете типа на Result<Vec<String>, io::Error> и да промените реда

let data: Vec<&str> = string.split('\n').collect();

to

let data: Vec<String> = string.split('\n').map(String::from).collect();
person fjh    schedule 22.10.2015
comment
Благодаря, знаех си, че ще е нещо тривиално. Предполагам, че трябва да промените и типа Vec на String в последния ред. - person estw272; 22.10.2015
comment
@ehsisthatsweird Прав си, пропуснах това. Между другото, анотацията за тип не трябва да е необходима тук, изводът за тип може да се справи с този случай. - person fjh; 22.10.2015