Почему моя переменная не живет достаточно долго?

У меня есть простой фрагмент кода, который должен читать файл в вектор по строкам

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