Чтение файла с Rust - заимствованное значение доживает только здесь - PullRequest
0 голосов
/ 04 июля 2018

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

fn read (file_name: &str) -> &str {

    let mut f = File::open(file_name)
        .expect(&format!("file not found: {}", file_name));

    let mut contents = String::new();

    f.read_to_string(&mut contents)
        .expect(&format!("cannot read file {}", file_name));

    return &contents;
}

Но я получаю эту ошибку:

  --> src\main.rs:20:13
   |
20 |     return &contents;
   |             ^^^^^^^^ borrowed value does not live long enough
21 | }
   | - borrowed value only lives until here
   |

Что я делаю не так?

Моя идея о том, что происходит здесь, такова:

  1. let mut f = File::open(file_name).expect(....); - он берет дескриптор файла и сообщает ОС, что мы хотим с ним что-то делать.

  2. let mut contents = String::new(); - это создает векторную структуру данных в куче для хранения данных, которые мы собираемся прочитать из файла.

  3. f.read_to_string(&mut contents).expect(...); - считывает файл в contents пространство.

  4. return &contents; - возвращает указатель на вектор, в котором хранятся данные файла.

Почему я не могу вернуть нужный мне указатель?

Как мне закрыть файл (переменная f)? Я думаю, что ржавчина закроет его для меня после того, как переменная выйдет из области видимости, но что, если мне нужно закрыть ее до этого?

1 Ответ

0 голосов
/ 04 июля 2018

Вы правы в том, что дескриптор файла закрывается автоматически, когда его переменная выходит из области видимости; то же самое случится и с contents - оно будет уничтожено в конце функции, если вы не решите вернуть его как принадлежащее String. В Rust функции не могут возвращать ссылки на объекты, созданные внутри них, только на те, которые переданы им в качестве аргументов.

Вы можете исправить свою функцию следующим образом:

fn read(file_name: &str) -> String {
    let mut f = File::open(file_name)
        .expect(&format!("file not found: {}", file_name));

    let mut contents = String::new();

    f.read_to_string(&mut contents)
        .expect(&format!("cannot read file {}", file_name));

    contents
}

Кроме того, вы можете передать contents в качестве изменяемой ссылки на функцию read:

fn read(file_name: &str, contents: &mut String) { ... }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...