rust - पॉइंटर के स्थानांतरित होने के बाद एक पॉइंटर के सदस्य को क्यों अभी भी मान्य है?



(1)

यह सूचक या नहीं होने के साथ करने के लिए कुछ भी नहीं है; यह भी काम करता है:

#[derive(Debug)]
struct NonCopy;

#[derive(Debug)]
struct Example {
    name: NonCopy,
}

fn main() {
    let mut foo = Example {
        name: NonCopy,
    };

    drop(foo);

    foo.name = NonCopy;
}

यद्यपि मुझे ऐसे समान सवाल नहीं मिल रहा है जो मुझे पता है कि मैंने पहले देखा है, निकोमात्साकिस से यह बोली इसका वर्णन करता है:

सामान्य चाल में ग्रैन्युलैरिटी का एक बहुत ही संकीर्ण स्तर पर ट्रैक किया जाता है। हम अंततः आपको दोनों क्षेत्रों को वापस "भरने" करने की इजाज़त देते हैं और फिर संरचना फिर से उपयोग करें मुझे लगता है कि आज काम नहीं करता है मुझे चाल कोड पर फिर से देखना पड़ता है, लेकिन मुझे लगता है कि सामान्य रूप से मैं पोस्ट 1 का पीछा करना चाहूंगा। वह चीजों के साथ बेहतर तरीके से निपटने के लिए प्रकार की व्यवस्था को बढ़ा रही है (विशेष रूप से मैं समर्थन करना चाहता हूं जब तक आप कुछ भी गलत होने से पहले मूल्य को पुनर्स्थापित करते हैं, तब तक & mut पॉइंटर्स से निकल जाते हैं)। वैसे भी मुझे लगता है कि यह उदाहरण अधिक या कम एक सामान्य तरीके से चीजों के इलाज से बाहर निकलता है, यद्यपि आप नियमों की कल्पना कर सकते हैं जो कहते हैं, "यदि आप च चले जाते हैं, तो आप फिर से किसी इकाई के रूप में च को पुनर्स्थापित किए बिना किसी भी उपक्षेत्र को छू नहीं सकते"।

रतुआ उपभेद पर भी चर्चा है, जो जंग मुद्दा 21232 से संबंधित है: "उधार-चक्कर की संरचना के आंशिक पुनर्जीवित की अनुमति देता है जिसे हटा दिया गया है, लेकिन इसका उपयोग नहीं"

संकल्पनात्मक रूप से, संरचना के अलावा किसी संरचना में प्रत्येक फ़ील्ड के लिए एक ध्वज है - मुझे क्रिस मॉर्गन के कार्डबोर्ड बॉक्स सादृश्य के बारे में सोचना चाहिए। जब आप संरचना का उपयोग करने से पहले वापस ले जाते हैं तो आप किसी स्वामित्व वाली संरचना के क्षेत्र से बाहर निकल सकते हैं:

drop(foo.name);
foo.name = NonCopy;

println!("{:?}", foo);

जाहिर है, 2014 के बाद से, कोई भी इस क्षेत्र में फिर से भरने के बाद पूरे ढांचे को वैध के रूप में चिह्नित करने में सक्षम बनाने के प्रयास में परेशान नहीं हुआ है।

वास्तव में, आपको वास्तव में इस कार्यक्षमता की आवश्यकता नहीं है क्योंकि आप एक बार में संपूर्ण चर को निर्दिष्ट कर सकते हैं। वर्तमान क्रियान्वयन अति-सुरक्षित है क्योंकि जंग आपको कुछ ऐसा करने से रोका जा रहा है जो ठीक लगता है।

इस उदाहरण में n1_mut अभी भी मान्य क्यों है? इसे Option::Some में ले जाया गया है, तो यह अमान्य नहीं होना चाहिए?

struct MyRecordRec2<'a> {
    pub id: u32,
    pub name: &'a str,
    pub next: Box<Option<MyRecordRec2<'a>>>
}

#[test]
fn creating_circular_recursive_data_structure() {
    let mut n1_mut = MyRecordRec2 {
        id: 1,
        name: "n1",
        next: Box::new(None)
    };

    let n2 = MyRecordRec2 {
        id: 2,
        name: "n2",
        next: Box::new(Some(n1_mut))
    };

    //Why is n1_mut still valid?
    n1_mut.next = Box::new(Some(n2));
}

निम्नलिखित परिचित "स्थानांतरित मूल्य का उपयोग" त्रुटि के साथ संकलन नहीं करता है:

#[test]
fn creating_and_freezing_circular_recursive_data_structure() {
    let loop_entry = {
        let mut n1_mut = MyRecordRec2 {
            id: 1,
            name: "n1",
            next: Box::new(None),
        };

        let n2 = MyRecordRec2 {
            id: 2,
            name: "n2",
            next: Box::new(Some(n1_mut)),
        };

        n1_mut.next = Box::new(Some(n2));

        n1_mut
    };
}
error[E0382]: use of moved value: `n1_mut`
  --> src/main.rs:44:9
   |
39 |             next: Box::new(Some(n1_mut)),
   |                                 ------ value moved here
...
44 |         n1_mut
   |         ^^^^^^ value used here after move
   |
   = note: move occurs because `n1_mut` has type `MyRecordRec2<'_>`, which does not implement the `Copy` trait




rust