मैं स्टड से लाइनें क्यों नहीं पढ़ सकता, व्हाट्सएप को हटा सकता हूं और उन्हें वेक्टर में धकेल सकता हूं? `लाइन` लंबे समय तक नहीं रहता है [डुप्लिकेट]

Aug 17 2020

मैं स्टड से लाइनें पढ़ना चाहूंगा, व्हॉट्सएप हटाऊंगा और उन्हें एक वेक्टर में धकेल दूंगा लेकिन मैं ऐसा नहीं कर सकता क्योंकि 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। स्पष्ट रूप से यह इसलिए है क्योंकि वे मूल स्ट्रिंग का एक विकल्प नहीं देते हैं, इसलिए उन्हें एक नया बनाना होगा।

टीएल; डीआर; आपके पास एक उधार है, &strलेकिन आप Stringअपने स्टोर में एक स्वामित्व चाहते हैं Vec। बस जोड़ते हैं .to_string()

चढ़ाव के बारे में, यह एक नया आवंटित करेगा String। आप इसे trimजगह में करने से बचने की कोशिश कर सकते हैं , लेकिन मुझे नहीं लगता कि यह इसके लायक है, जब तक कि आप प्रोफ़ाइल नहीं करते हैं और आप तय करते हैं कि आपकी ट्रिमिंग आपके प्रदर्शन को नुकसान पहुंचा रही है।