Perché non riesco a leggere le righe da stdin, rimuovere gli spazi bianchi e inserirle in un vettore? "line" non vive abbastanza a lungo [duplicato]

Aug 17 2020

Vorrei leggere le righe da stdin, rimuovere gli spazi bianchi e inserirle in un vettore ma non posso perché linenon vive abbastanza a lungo. Perché?

use std::io::{self, BufRead};

fn main() {
    let stdin = io::stdin();
    let mut read = Vec::new();
    for line in stdin.lock().lines() {
        let line = line.unwrap();
        let line = line.trim();
        read.push(line);
    }
}
error[E0597]: `line` does not live long enough
  --> src/main.rs:8:20
   |
8  |         let line = line.trim();
   |                    ^^^^ borrowed value does not live long enough
9  |         read.push(line);
   |         ---- borrow later used here
10 |     }
   |     - `line` dropped here while still borrowed

Risposte

2 rodrigo Aug 17 2020 at 15:39

Se guardi la definizione di str::trim()(annotazioni a vita aggiunte):

pub fn trim<'a>(&'a self) -> &'a str

Puoi vedere che restituisce una sezione di stringa che fa riferimento a una parte della stringa originale. Cioè, prende in prestito la stringa invece di copiarla. Il che ha senso, perché il risultato di trimè sempre una sottostringa dell'originale.

Potresti essere confuso da altre funzioni, come,, str::to_uppercase()che restituiscono un nuovo String. Ovviamente questo è perché non restituiscono una sottostringa della stringa originale, quindi devono crearne una nuova.

TL; DR; Hai un prestito &strma vuoi un possedimento Stringda conservare nel tuo Vec. Basta aggiungere .to_string().

Riguardo agli svantaggi, assegnerà un nuovo file String. Potresti provare a evitarlo facendo un trimposto , ma non penso che ne valga la pena, a meno che tu non faccia il profilo e decidi che il tuo taglio sta danneggiando le tue prestazioni.