Mengapa saya tidak dapat membaca baris dari stdin, menghapus spasi dan mendorongnya dalam vektor? `line` tidak hidup cukup lama [duplikat]

Aug 17 2020

Saya ingin membaca baris dari stdin, menghapus spasi dan mendorongnya ke dalam vektor tetapi saya tidak bisa karena linetidak hidup cukup lama. Mengapa?

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

Jawaban

2 rodrigo Aug 17 2020 at 15:39

Jika Anda melihat definisi str::trim()(anotasi seumur hidup ditambahkan):

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

Anda dapat melihat bahwa ia mengembalikan potongan string yang merujuk ke bagian dari string asli. Artinya, ia meminjam string alih-alih menyalinnya. Yang masuk akal, karena hasil dari trimselalu merupakan substring dari aslinya.

Anda mungkin bingung dengan fungsi lain, seperti str::to_uppercase(),, yang mengembalikan baru String. Jelas ini karena mereka tidak mengembalikan substring dari string asli, jadi mereka harus membuat yang baru.

TL; DR; Anda memiliki pinjaman &strtetapi Anda ingin memiliki milik Stringuntuk disimpan di Vec. Tambahkan saja .to_string().

Tentang kerugiannya, itu akan mengalokasikan yang baru String. Anda dapat mencoba menghindarinya dengan melakukan trimdi tempat , tetapi menurut saya itu tidak sepadan, kecuali Anda membuat profil dan Anda memutuskan bahwa pemangkasan Anda merusak kinerja Anda.