Почему я не могу читать строки из стандартного ввода, удалять пробелы и вставлять их в вектор? `line` не живет достаточно долго [дубликат]

Aug 17 2020

Я хотел бы читать строки из stdin, удалять пробелы и вставлять их в вектор, но я не могу, потому lineчто не живет достаточно долго. Почему?

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

Ответы

2 rodrigo Aug 17 2020 at 15:39

Если вы посмотрите на определение str::trim()(добавлены аннотации времени жизни):

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

Вы можете видеть, что он возвращает фрагмент строки, который относится к части исходной строки. То есть он заимствует строку, а не копирует ее. Что имеет смысл, потому что результат trimвсегда является подстрокой исходной.

Вас могут смутить другие функции, например,, str::to_uppercase()которые возвращают новый String. Очевидно, это связано с тем, что они не возвращают подстроку исходной строки, поэтому им нужно создать новую.

TL; DR; У вас есть заимствованный, &strно вы хотите, чтобы принадлежащий Stringхранится в вашем Vec. Просто добавь .to_string().

Из минусов выделю новый String. Вы можете попытаться избежать этого, сделав на trimместе , но я не думаю, что оно того стоит, если только вы не профилируете и не решите, что обрезка вредит вашей производительности.