stdinから行を読み取り、空白を削除してベクトルにプッシュできないのはなぜですか?`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インプレースでそれを回避することもできますが、プロファイルを作成し、トリミングによってパフォーマンスが低下していると判断しない限り、それだけの価値はないと思います。