2015-02-01 3 views
10

मैं जंगली जीवनकाल, स्वामित्व और संदर्भों के आस-पास अपने सिर को लपेटने के लिए एक लिंक्ड सूची लिख रहा हूं। मैं निम्नलिखित कोड है:स्वामित्व स्थानांतरित करने का प्रयास करते समय उधारित सामग्री से बाहर नहीं जा सकता

pub struct LinkedList { 
    head: Option<Box<LinkedListNode>>, 
} 

pub struct LinkedListNode { 
    next: Option<Box<LinkedListNode>>, 
} 

impl LinkedList { 
    pub fn new() -> LinkedList { 
     LinkedList { head: None } 
    } 

    pub fn prepend_value(&mut self) { 
     let mut new_node = LinkedListNode { next: None }; 

     match self.head { 
      Some(ref head) => new_node.next = Some(*head), 
      None => new_node.next = None, 
     }; 

     self.head = Some(Box::new(new_node)); 
    } 
} 

fn main() {} 

लेकिन मैं निम्नलिखित संकलन त्रुटि हो रही है:

error[E0507]: cannot move out of borrowed content 
    --> src/main.rs:18:52 
    | 
18 |    Some(ref head) => new_node.next = Some(*head), 
    |             ^^^^^ cannot move out of borrowed content 

मैं सोच रहा हूँ कि head नोड वर्तमान में self के स्वामित्व में किया जाना चाहिए, जो लिंक्ड सूची है। जब मैं इसे new_node.next पर असाइन करता हूं, तो संभवतः स्वामित्व में बदलाव होता है जो होगा।

यदि संभव हो तो मैं मूल्य को क्लोन नहीं करूँगा क्योंकि यह अपमानजनक लगता है। मैं फ़ंक्शन की अवधि के लिए इसे "उधार" नहीं लेना चाहता हूं। मैं वास्तव में अपने स्वामित्व को स्थानांतरित करना चाहता हूं।

मैं यह कैसे कर सकता हूं?

मैंने पहले से ही error: cannot move out of borrowed content on &mut self और Cannot move out of borrowed content देखा है।

मैंने उन प्रश्नों में से एक में स्वीकृत उत्तर में सुझाए गए मैच आर्मी को हटाने और next को नए LinkedListNode के निर्माण में परिभाषित करने का प्रयास किया, लेकिन मुझे एक ही त्रुटि संदेश मिलता है।

मैंने सफलतापूर्वक append विधि को सफलतापूर्वक जोड़ा है जो सूची के अंत में जोड़ने के लिए LinkedListNode लेता है।

+0

के संभावित डुप्लिकेट [\ '\ की भिन्नता से बाहर नहीं ले जा सकते' और mut \ '-pointer \' एक हल कर लिंक्ड सूची के निर्माण, जबकि] (http : //stackoverflow.com/questions/27750985/cannot-move-out-of-dereference-of-mut-pointer-while-building-a-sorted-linke) – Shepmaster

उत्तर

19

Cannot move out of borrowed content when trying to transfer ownership

उच्च स्तर पर, यह जंग के लिए अनाज है। आप उधार लेने वाले किसी चीज़ के स्वामित्व को स्थानांतरित नहीं कर सकते हैं क्योंकि आपके पास नहीं है। आपको उधार नहीं लेना चाहिए (&Foo) मेरी कार और फिर इसे सड़क पर देखे गए पहले व्यक्ति को दें! यह अभी भी सच है भले ही मैं आपको अपनी कार उधार देता हूं और आपको इसमें बदलाव करने की अनुमति देता हूं (&mut Foo)।

आप एक &mut self से बाहर है और एक नए नोड क्योंकि इस एक असंगत स्थिति में LinkedList struct छोड़ना होगा में head स्थानांतरित नहीं कर सकते - क्षेत्रों में से एक एक अपरिभाषित मूल्य होगा। यह जंग की सुरक्षा गारंटी का एक मूल उपाय है।

इस मामले में, आप Option::take का उपयोग कर सकते हैं। यह उस चर को छोड़ देगा जहां यह है, इसे None पर स्थानांतरित करना और पिछले मान को वापस करना। इसके बाद आप सूची के नए प्रमुख के निर्माण के लिए है कि मूल्य का उपयोग कर सकते हैं:

pub fn prepend_value(&mut self) { 
    let head = self.head.take(); 
    self.head = Some(Box::new(LinkedListNode { next: head })); 
} 

एक अधिक सामान्य समाधान यह उधार लेने की बजाय struct का स्वामित्व लेने के लिए है। यह आपको जो कुछ भी करना चाहते हैं उसे करने की अनुमति देता है। ध्यान दें कि हम दर-मूल्य self लेते हैं, द्वारा-संदर्भ नहीं:

pub fn prepend_value(mut self) -> LinkedList { 
    self.head = Some(Box::new(LinkedListNode { next: self.head })); 
    self 
} 
+0

आप जो दो समाधान कहेंगे, वह अधिक मूर्ख कोड है ? – Gilles

+1

चूंकि आपके पास 'नोड' और एक रैपर 'सूची' है, इसलिए शायद मैं' टेक 'के साथ संस्करण का उपयोग करूंगा; मुझे लगता है कि लोग 'स्वयं' से अधिक 'और mut self' को समझते हैं। अगर सूची सिर्फ 'नोड' से बनी थी, तो आपको 'स्वयं' संस्करण का उपयोग करना होगा।मैं उपयोगकर्ताओं को मार्गदर्शन करने में सहायता के लिए शायद इसे '# [must_use] 'के रूप में भी एनोटेट कर दूंगा। – Shepmaster

संबंधित मुद्दे