2015-05-29 3 views
13

इस कोड में विफल रहता है संकलन त्रुटि के साथ let c = a; में अपेक्षा के अनुरूप "चले गए मूल्य के उपयोग: a":परिवर्तनीय बाध्यकारी: एक और म्यूट या स्थानांतरण को उधार लेना?

fn main() { 
    let a: &mut i32 = &mut 0; 
    let b = a; 
    let c = a; 
} 

एक ख में चले गए और ग के लिए असाइनमेंट को अब उपलब्ध नहीं है है। अब तक सब ठीक है.

हालांकि, अगर मैं सिर्फ b के प्रकार व्याख्या और सब कुछ किसी और अकेला छोड़ दो:

fn main() { 
    let a: &mut i32 = &mut 0; 
    let b: &mut i32 = a; 
    let c = a; 
} 

कोड let c = a;

में फिर से विफल रहता है लेकिन एक बहुत अलग त्रुटि संदेश के साथ इस बार: "स्थानांतरित नहीं कर सकते a क्योंकि यह उधार लिया जाता है से बाहर ... *a की उधार यहां होती है: let b: &mut i32 = a; "

तो, अगर मैं सिर्फ व्याख्या b के प्रकार: n o ab में स्थानांतरित करें, लेकिन इसके बजाय *a का "पुनः" -बोरो?

मुझे क्या याद आ रही है?

चीयर्स। b में a का कोई चाल, लेकिन बजाय एक *a की -borrow "फिर":

उत्तर

7

तो, अगर मैं सिर्फ व्याख्या b के प्रकार?

मुझे क्या याद आ रही है?

बिल्कुल कुछ भी नहीं

, इस मामले में के रूप में इन दो आपरेशन शब्दार्थ बहुत समान हैं (और बराबर अगर a और b एक ही दायरे के हैं)।

  • या तो आप b में संदर्भ a ले जाते हैं, a एक चले गए मूल्य, और अब उपलब्ध नहीं बना रही है।
  • या तो में *a को फिर से घुमाएं, b को अनुपयोगी बनाते समय अनुपयोगी बनाते हैं।

दूसरा मामला पहले से कम निश्चित है, तो आप b को उप-स्कोप में परिभाषित लाइन डालकर इसे दिखा सकते हैं।

यह उदाहरण संकलन नहीं क्योंकि a ले जाया जाता है:

fn main() { 
    let a: &mut i32 = &mut 0; 
    { let b = a; } 
    let c = a; 
} 

लेकिन यह एक होगा, क्योंकि एक बार b गुंजाइश a के बाहर चला जाता है अनलॉक हो गया है:

fn main() { 
    let a: &mut i32 = &mut 0; 
    { let b = &mut *a; } 
    let c = a; 
} 

अब, करने के लिए सवाल "b के प्रकार को एनोटेट करने का व्यवहार क्यों बदलता है?", मेरा अनुमान होगा:

  • जब कोई प्रकार की एनोटेशन नहीं होती है, तो ऑपरेशन एक सरल और सीधा कदम है।जांचने के लिए कुछ भी जरूरी नहीं है।
  • जब कोई प्रकार की एनोटेशन होती है, तो एक रूपांतरण की आवश्यकता हो सकती है (&mut _ को &_ में डालना, या एक विशेषता संदर्भ के संदर्भ में एक साधारण संदर्भ को परिवर्तित करना)। तो संकलक एक कदम के बजाय मूल्य के पुन: उधार लेने का विकल्प चुनता है।

उदाहरण के लिए, इस कोड को perflectly मान्य है:

fn main() { 
    let a: &mut i32 = &mut 0; 
    let b: &i32 = a; 
} 

और यहाँ b में a चलती कोई मतलब नहीं होता है, के रूप में वे अलग अलग प्रकार के हैं। अभी भी यह कोड संकलित करता है: b बस *a फिर से उधार लेता है, और a के माध्यम से मूल्य पारस्परिक रूप से उपलब्ध नहीं होगा जब तक b गुंजाइश में है।

+0

उत्तर के लिए Thx Levans। वास्तव में यह सत्यापित करने के लिए कि वास्तव में '* ए' का उधार लिया गया था, मैंने सबस्कॉप संस्करण को चेक किया था। आखिरकार, एक झूठा संकलक संदेश हो सकता था। आपके अनुमान के संबंध में, अगर मैं टाइप एनोटेशन का उपयोग करता हूं तो मुझे बहुत असहज महसूस होता है, मुझे स्पष्ट अर्थ के कुछ अजीब पुनः लिखने के लिए तैयार रहना होगा: 'ए = बी;' हमेशा एक चाल या प्रतिलिपि होना चाहिए, प्रकार एनोटेटेड या नहीं। – dacker

+0

@ डैकर अच्छी तरह से, ध्यान रखें कि यह व्यवहार * केवल * 'और mut 'संदर्भों के साथ पहुंचा जा सकता है, इस मामले में पुन: उधार केवल एक प्रति है जो उधार नियमों का सम्मान करता है। – Levans

+0

लेकिन क्या मैंने उन सभी दस्तावेज़ों में एक बड़ा मुद्दा नहीं देखा है जिन्हें मैंने अभी तक पढ़ा है: और इन मामलों में हमेशा म्यूटियां चली जाती हैं? एनबी: ऊपर जैसा ही व्यवहार एनोटेटेड और मट्स टाइप करने के लिए असाइनमेंट के साथ होता है। – dacker

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