Não é possível dividir uma sequência em fatias de sequência com vida útil explícita porque a sequência não dura o tempo suficiente
Estou escrevendo uma biblioteca que deve ler algo implementando oBufRead
traço; um fluxo de dados da rede, entrada padrão etc. A primeira função deve ler uma unidade de dados desse leitor e retornar uma estrutura preenchida preenchida principalmente com&'a str
valores analisados de um quadro do fio.
Aqui está uma versão mínima:
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);
}
Aparece um erro que não consigo corrigir depois de tentar soluções diferentes:
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 vida'a
é definido em uma estrutura e implementação de uma estrutura de detentor de dados porque o&str
requer uma vida útil explícita. Essas partes do código foram removidas como parte do exemplo mínimo.
BufReader
tem umlines()
método que retornaResult<String, Err>
. Lido com erros usandoexpect
oumatch
e, assim, desembalar oResult
para que o programa agora tenha a nuString
. Isso será feito várias vezes para preencher uma estrutura de dados.
Muitas respostas dizem que ounwrap
O resultado precisa estar vinculado a uma variável, caso contrário, ele se perde porque é um valor temporário. Mas eu já salvei o pacoteResult
valor na variávelline
e ainda recebo o erro.
Como corrigir este erro - não foi possível fazê-lo funcionar após horas tentando.
Faz sentido fazer todas essas declarações vitalícias apenas para&str
em uma estrutura de detentor de dados? Essa será principalmente uma estrutura de dados somente leitura, no máximo substituindo valores de campo inteiro.String
também poderia ser usado, mas encontraram artigos dizendo queString
tem desempenho inferior ao&str
- e essa função de analisador de quadros será chamada várias vezes e é crítica para o desempenho.
Perguntas semelhantes existem no Stack Overflow, mas nenhuma responde bem à situação aqui.
Para maior abrangência e melhor entendimento, segue um trecho do código fonte completo sobre o motivo pelo qual a pergunta vitalícia surgiu:
Declaração da estrutura de dados:
// 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!");
}
}
Definição de função completa:
pub fn parse_frame<'a, T>(mut reader: T) -> Result<Frame<'a>, io::Error> where T: BufRead {