2015-01-12 4 views
5

मुझे जंग में ref पैटर्न को समझने में समस्याएं हैं। मैं https://rustbyexample.com/scope/borrow/ref.htmlउदाहरण के आधार पर जंग: रेफ पैटर्न

यहाँ की चर्चा करते हुए कर रहा हूँ कोड मुझे समझ नहीं आता है:

let point = Point { x: 0, y: 0 }; 

let _copy_of_x = { 
    // `ref_to_x` is a reference to the `x` field of `point` 
    let Point { x: ref ref_to_x, y: _ } = point; 

    // Return a copy of the `x` field of `point` 
    *ref_to_x 
}; 

मैं कि पिछले let अभिव्यक्ति पैटर्न मिलान के कुछ प्रकार है (?)। तो यह मेरी समझ है ref ref_to_x0 के बराबर होना चाहिए, मूल point का मान होना चाहिए।

लेकिन मुझे नहीं पता कि ref वास्तव में क्या करता है। जब मैं इस तरह की कुछ कोड जोड़ें:

println!("x: {}", point.x); 
println!("ref_to_x: {}", ref_to_x); 
println!("*ref_to_x: {}", *ref_to_x); 

मैं हमेशा 0 मिलता है, तो वहाँ एक अंतर होने के लिए प्रतीत नहीं होता। किसी भी तरह से मैं ref_to_x के लिए मेमोरी एड्रेस की अपेक्षा करता हूं जबकि *ref_to_x फिर से संदर्भित मान हो सकता है।

मैं ref ref_to_x और *ref_to_x दोनों myx के साथ प्रतिस्थापित कर सकता हूं और कोड अभी भी काम करता है। क्या फर्क पड़ता है? ref वास्तव में क्या करता है?

संपादित करें: dbaupps उत्तर पढ़ने और ref_to_x और *ref_to_x के साथ कुछ अतिरिक्त करने के बाद कुछ स्पष्ट हो गया; आप ref_to_x पर एक पूर्णांक नहीं जोड़ सकते क्योंकि यह एक संदर्भ है। मुझे लगता है कि मैं उलझन में आया क्योंकि जब आप प्रिंट करते हैं तो संदर्भ का कोई संकेत नहीं होता है।

उत्तर

10

ref, स्मृति का टुकड़ा है कि पर मिलान किया जा रहा, इस मामले में में एक सूचक बनाता ref_to_x स्मृति कि point.x संग्रहीत करता है करने के लिए सीधे इशारा कर रही है, यह इस मामले में let ref_to_x = &point.x लेखन के समान है।

पैटर्न बेहद महत्वपूर्ण है, क्योंकि यह स्वामित्व पदानुक्रम को परेशान किए बिना जटिल डेटा-संरचनाओं के अंदर गहराई तक पहुंचने की अनुमति देता है। उदाहरण के लिए, अगर एक val: &Option<String>, लेखन

match *val { 
    Some(s) => println!("the string is {}", s), 
    None => println!("no string" 
} 

कानूनी नहीं दे रहा है, ऐसा लगता है एक त्रुटि देता है:

<anon>:3:11: 3:15 error: cannot move out of borrowed content 
<anon>:3  match *val { 
        ^~~~ 
<anon>:4:14: 4:15 note: attempting to move value to here 
<anon>:4   Some(s) => {} 
        ^
<anon>:4:14: 4:15 help: to prevent the move, use `ref s` or `ref mut s` to capture value by reference 
<anon>:4   Some(s) => {} 
        ^

यह एक उधार मूल्य से बाहर स्वामित्व (चाल) लेने के लिए कानूनी नहीं है, क्योंकि जो संभवतः उस चीज़ को नुकसान पहुंचाएगा जिस से मूल्य उधार लिया गया था (इसके आविष्कारों का उल्लंघन करना, जिससे डेटा अप्रत्याशित रूप से गायब हो गया, आदि)।

तो, कोई व्यक्ति उधार लेने के साथ स्मृति में केवल & संदर्भ के संदर्भ में संदर्भ का उपयोग कर सकता है।


वहाँ एक मामूली सूक्ष्मता यहाँ, क्योंकि (क) point उधार नहीं है इसलिए इसमें (जो भी point के मालिकाना हक की खपत है, यह अर्थ बाद में नहीं किया जा सकता जब तक कि reinitialised) point से बाहर स्थानांतरित करने के लिए ठीक है , और (बी) प्रकार intCopy है, इसलिए मान द्वारा उपयोग किए जाने पर स्वामित्व को स्थानांतरित नहीं किया जाता है। यही कारण है कि myx का उपयोग करना ठीक काम करता है। यदि x का प्रकार, String (जो Copy नहीं है) और point उधार लिया गया था, तो ref आवश्यक होगा।

11

ref के साथ बनाया गया एक संदर्भ बिल्कुल & के साथ संदर्भ के समान है।

अंतर यह है कि उन्हें वाक्यविन्यास में अनुमति दी जाती है। असाइनमेंट के बाईं तरफ ref दाएं तरफ & जोड़ना है। एक नया एक बनाने के लिए बजाय

let ref x1 = y; 
let x2 = &y; 

यह अतिरेक मौजूद है क्योंकि मिलान & पैटर्न में आवश्यक है कि एक संदर्भ पहले से मौजूद है प्रयोग किया जाता है,:

let foo = 1; 
match foo { 
    ref x => { 
     /* x == &1 */ 
     match x { 
      &y => /* y == 1 */ 
     } 
    }, 
} 

(

ये भाव बराबर हैं discussion)