Pourquoi ne puis-je pas lire les lignes de stdin, supprimer les espaces et les insérer dans un vecteur? `line` ne vit pas assez longtemps [dupliquer]
Je voudrais lire les lignes de stdin, supprimer les espaces et les pousser dans un vecteur mais je ne peux pas car line
ne vit pas assez longtemps. Pourquoi?
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
Réponses
Si vous regardez la définition de str::trim()(annotations à vie ajoutées):
pub fn trim<'a>(&'a self) -> &'a str
Vous pouvez voir qu'il renvoie une tranche de chaîne qui fait référence à une partie de la chaîne d'origine. Autrement dit, il emprunte la chaîne au lieu de la copier. Ce qui a du sens, car le résultat de trim
est toujours une sous-chaîne de l'original.
Vous pouvez être dérouté par d'autres fonctions, telles str::to_uppercase()que,, qui renvoient un nouveau String
. C'est évidemment parce qu'ils ne renvoient pas une sous-chaîne de la chaîne d'origine, ils doivent donc en créer une nouvelle.
TL, DR; Vous avez un emprunté &str
mais vous souhaitez qu'un propriétaire String
stocke dans votre Vec
. Ajoutez simplement .to_string()
.
A propos des inconvénients, il allouera un nouveau String
. Vous pouvez essayer de l'éviter en faisant un trimsur place , mais je ne pense pas que cela en vaille la peine, à moins que vous ne profiliez et que vous décidiez que votre coupe nuit à votre performance.