उधार ली गई सामग्री से बाहर नहीं जा सकते / साझा संदर्भ के पीछे नहीं हट सकते


127

मैं त्रुटि नहीं समझता cannot move out of borrowed content। मैंने इसे कई बार प्राप्त किया है और मैंने हमेशा इसे हल किया है, लेकिन मैंने कभी नहीं समझा कि क्यों।

उदाहरण के लिए:

for line in self.xslg_file.iter() {
    self.buffer.clear();

    for current_char in line.into_bytes().iter() {
        self.buffer.push(*current_char as char);
    }

    println!("{}", line);
}

त्रुटि पैदा करता है:

error[E0507]: cannot move out of borrowed content
  --> src/main.rs:31:33
   |
31 |             for current_char in line.into_bytes().iter() {
   |                                 ^^^^ cannot move out of borrowed content

रस्ट के नए संस्करणों में, त्रुटि है

error[E0507]: cannot move out of `*line` which is behind a shared reference
  --> src/main.rs:31:33
   |
31 |             for current_char in line.into_bytes().iter() {
   |                                 ^^^^ move occurs because `*line` has type `std::string::String`, which does not implement the `Copy` trait

मैंने इसे क्लोन करके हल किया line:

for current_char in line.clone().into_bytes().iter() {

अन्य पदों को पढ़ने के बाद भी मुझे त्रुटि समझ में नहीं आई:

इस तरह की त्रुटि का मूल क्या है?


1
क्या आपने इस तरह के सवालों पर गौर किया है ? (Btw, तार .bytes()विधि की पेशकश करते हैं ।)
huon

हां, मैंने इसे देखा, लेकिन समझ में नहीं आया :( और मेरा स्ट्रिंग एक std :: string :: string है, प्रलेखन के अनुसार, कोई भी नहीं है। () विधि
Peekmo

4
यह कहा जाता है.as_bytes()
दोष

वास्तव में, धन्यवाद, यह as_bytes()क्लोनिंग के बिना काम करता है । लेकिन मुझे अभी भी समझ नहीं आया कि क्यों?
पीकोमो

Stringसे bytesविधि प्राप्त करता है str
हून

जवाबों:


108

आइए इसके लिए हस्ताक्षर देखें into_bytes:

fn into_bytes(self) -> Vec<u8>

यह selfस्वयं के संदर्भ में नहीं है ( &self)। इसका मतलब है कि selfहो जाएगा सेवन किया और कॉल के बाद उपलब्ध नहीं होगा। इसकी जगह पर आपको ए Vec<u8>। उपसर्ग into_इस तरह के तरीकों को दर्शाने का एक सामान्य तरीका है।

मुझे नहीं पता कि आपका iter()तरीका क्या है, लेकिन मेरा अनुमान है कि यह एक पुनरावृत्ति है &String, यानी यह संदर्भ देता है Stringलेकिन आपको इनका स्वामित्व नहीं देता है। इसका मतलब है कि आप एक ऐसी विधि नहीं कह सकते हैं जो मूल्य का उपभोग करती है

जैसा कि आपने पाया है, एक समाधान का उपयोग करना है clone। यह एक डुप्लिकेट ऑब्जेक्ट बनाता है जिसे आप स्वयं करते हैं, और कॉल कर सकते हैं into_bytes। जैसा कि अन्य टिप्पणीकारों का उल्लेख है, आप भी उपयोग कर सकते हैं as_bytesजो लेता है &self, इसलिए यह उधार मूल्य पर काम करेगा। आपको किसका उपयोग करना चाहिए, यह आपके अंतिम लक्ष्य पर निर्भर करता है कि आप सूचक के साथ क्या करते हैं।

बड़ी तस्वीर में, यह सब स्वामित्व की धारणा के साथ करना है । कुछ संचालन आइटम के मालिक होने पर निर्भर करते हैं, और अन्य संचालन वस्तु को उधार लेने से दूर हो सकते हैं (शायद पारस्परिक रूप से)। एक संदर्भ ( &foo) स्वामित्व प्रदान नहीं करता है, यह सिर्फ एक उधार है।

किसी फ़ंक्शन के तर्कों के selfबजाय इसका उपयोग करना दिलचस्प क्यों है &self?

स्वामित्व स्थानांतरित करना सामान्य रूप से एक उपयोगी अवधारणा है - जब मैं किसी चीज के साथ किया जाता हूं, तो किसी और के पास हो सकता है। जंग में, यह अधिक कुशल होने का एक तरीका है। मैं एक कॉपी आवंटित करने से बच सकता हूं, आपको एक कॉपी दे सकता हूं, फिर मेरी कॉपी को फेंक दूंगा। स्वामित्व भी सबसे अधिक अनुमति वाला राज्य है; यदि मेरी कोई वस्तु है तो मैं इसे अपनी इच्छानुसार कर सकता हूं।


यहाँ कोड है जिसे मैंने परीक्षण करने के लिए बनाया है:

struct IteratorOfStringReference<'a>(&'a String);

impl<'a> Iterator for IteratorOfStringReference<'a> {
    type Item = &'a String;

    fn next(&mut self) -> Option<Self::Item> {
        None
    }
}

struct FileLikeThing {
    string: String,
}

impl FileLikeThing {
    fn iter(&self) -> IteratorOfStringReference {
        IteratorOfStringReference(&self.string)
    }
}

struct Dummy {
    xslg_file: FileLikeThing,
    buffer: String,
}

impl Dummy {
    fn dummy(&mut self) {
        for line in self.xslg_file.iter() {
            self.buffer.clear();

            for current_char in line.into_bytes().iter() {
                self.buffer.push(*current_char as char);
            }

            println!("{}", line);
        }
    }
}

fn main() {}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.