Может быть, следующая программа дает подсказки для тех, у кого также есть первые проблемы с жизнями:

у библиотеку, которая должна читать что-то, реализующееBufRead черта характера; сетевой поток данных, стандартный ввод и т. д. Предполагается, что первая функция считывает блок данных из этого считывателя и возвращает заполненную структуру, заполненную в основном&'a str значения разбираются из кадра с провода.

Вот минимальная версия:

mod mymod {
    use std::io::prelude::*;
    use std::io;

    pub fn parse_frame<'a, T>(mut reader: T)
    where
        T: BufRead,
    {
        for line in reader.by_ref().lines() {
            let line = line.expect("reading header line");
            if line.len() == 0 {
                // got empty line; done with header
                break;
            }
            // split line
            let splitted = line.splitn(2, ':');
            let line_parts: Vec<&'a str> = splitted.collect();

            println!("{} has value {}", line_parts[0], line_parts[1]);
        }
        // more reads down here, therefore the reader.by_ref() above
        // (otherwise: use of moved value).
    }
}

use std::io;

fn main() {
    let stdin = io::stdin();
    let locked = stdin.lock();
    mymod::parse_frame(locked);
}

Появляется ошибка, которую я не могу исправить после попытки разных решений:

error: `line` does not live long enough
  --> src/main.rs:16:28
   |
16 |             let splitted = line.splitn(2, ':');
   |                            ^^^^ does not live long enough
...
20 |         }
   |         - borrowed value only lives until here
   |
note: borrowed value must be valid for the lifetime 'a as defined on the body at 8:4...
  --> src/main.rs:8:5
   |
8  | /     {
9  | |         for line in reader.by_ref().lines() {
10 | |             let line = line.expect("reading header line");
11 | |             if line.len() == 0 {
...  |
22 | |         // (otherwise: use of moved value).
23 | |     }
   | |_____^

Время жизни'a определяется в структуре и реализации структуры хранителя данных, потому что&str требует явного времени жизни. Эти части кода были удалены как часть минимального примера.

BufReader имеетlines() метод, который возвращаетResult<String, Err>, Я обрабатываю ошибки, используяexpect или жеmatch и, таким образом, распаковатьResult так что программа теперь имеет голоеString, Это будет сделано несколько раз для заполнения структуры данных.

Многие ответы говорят, чтоunwrap результат должен быть связан с переменной, иначе он теряется, потому что это временное значение. Но я уже сохранил распакованныйResult значение в переменнойline и я все еще получаю ошибку.

Как исправить эту ошибку - не смог заставить ее работать после нескольких часов попыток.

Имеет ли смысл делать все эти пожизненные объявления только для&str в структуре хранителя данных? Это будет в основном структура данных только для чтения, в большинстве случаев заменяющая целые значения полей.String также может быть использован, но нашел статьи о том, чтоString имеет более низкую производительность, чем&str - и эта функция синтаксического анализа кадров будет вызываться много раз и критична для производительности.

Подобные вопросы существуют в отношении переполнения стека, но ни один из них не совсем отвечает ситуации здесь.

Для полноты и лучшего понимания ниже приводится выдержка из полного исходного кода о том, почему возник вопрос на всю жизнь:

Объявление структуры данных:

// tuple
pub struct Header<'a>(pub &'a str, pub &'a str);

pub struct Frame<'a> {
    pub frameType: String,
    pub bodyType: &'a str,
    pub port: &'a str,
    pub headers: Vec<Header<'a>>,
    pub body: Vec<u8>,
}

impl<'a> Frame<'a> {
    pub fn marshal(&'a self) {
        //TODO
        println!("marshal!");
    }
}

Полное определение функции:

pub fn parse_frame<'a, T>(mut reader: T) -> Result<Frame<'a>, io::Error> where T: BufRead {

Ответы на вопрос(2)

Ваш ответ на вопрос