เหตุใดฉันจึงไม่สามารถอ่านบรรทัดจาก stdin ลบช่องว่างและดันเป็นเวกเตอร์ได้ "บรรทัด" ไม่ยาวพอ [ซ้ำ]

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ในสถานที่แต่ฉันไม่คิดว่ามันคุ้มค่าเว้นแต่คุณจะทำโปรไฟล์และตัดสินใจว่าการตัดแต่งของคุณทำให้ประสิทธิภาพของคุณแย่ลง