2015-12-18 9 views
6

मैं दो structs बनाने की कोशिश कर रहा हूं जो अंतर्निहित डेटासेट पर काम करते हैं; एक अपरिवर्तनीय "पढ़ा" संचालन प्रदान करता है, दूसरा संशोधन की अनुमति देता है। इसके लिए काम करने के लिए, मुझे संशोधित ऑब्जेक्ट के भीतर से पढ़ने के कार्यों का उपयोग करने में सक्षम होना चाहिए - जैसे कि मैं अंतर्निहित डेटा पर एक दृश्य के साथ संशोधक फ़ंक्शन के भीतर एक अस्थायी नई रीड ऑब्जेक्ट बनाता हूं।अंतर्निहित संदर्भ फ़ील्ड के जीवनकाल पर गुजर रहा है?

यहाँ कुछ कोड है:

struct Read<'db> { 
    x: &'db i32 
} 

impl<'db> Read<'db> { 
    pub fn get(&'db self) -> &'db i32 { self.x } 
} 

struct Write<'db> { 
    x: &'db mut i32 
} 

impl<'db> Write<'db> { 
    fn new(x: &mut i32) -> Write { Write{x: x} } 

    fn as_read(&'db self) -> Read<'db> { 
     Read{x: self.x} 
    } 

    pub fn get(&'db self) -> &'db i32 { self.as_read().get() } 
}  


fn main() { 
    let mut x = 69i32; 
    let y = Write::new(&mut x); 
    println!("{}", y.get()); 
} 

यह संकलन नहीं करता है - ऐसा लगता है के बजाय Write कि मेरे सबसे अच्छे प्रयासों के बावजूद, संदर्भ Read::get से लौटे के जीवनकाल Write::get की गुंजाइश के लिए बाध्य है 'db आजीवन। मैं इसे संकलित कैसे कर सकता हूं? (और, क्या मैं संभव करना चाहता हूं? क्या यह करने का सबसे सरल/सबसे संक्षिप्त तरीका है?)

उत्तर

4

जिस बिंदु पर संकलक पार करने की कोशिश कर रहा है वह यह है कि &'db self वास्तव में self: &'db Write<'db> है। इसका मतलब है कि आप संदर्भ और प्रकार को उसी जीवनकाल में बांधते हैं। आप वास्तव में अपने मामले में क्या चाहते हैं self: &'a Write<'db> जहां 'a केवल as_read फ़ंक्शन के लिए रहता है। 'db को 'a संदर्भ से संदर्भित करने में सक्षम होने के लिए, आपको को बाध्य करके कम से कम 'db तक निर्दिष्ट करना होगा।

fn as_read<'a: 'db>(self: &'a Write<'db>) -> Read<'db> { 
    Read{x: self.x} 
} 

pub fn get<'a: 'db>(self: &'a Write<'db>) -> &'db i32 { self.as_read().get() } 

या अधिक concisely

fn as_read<'a: 'db>(&'a self) -> Read<'db> { 
    Read{x: self.x} 
} 

pub fn get<'a: 'db>(&'a self) -> &'db i32 { self.as_read().get() } 

Try it out in the Playground

+0

क्या अजीब बात यह है कि अगर struct एक 'और mut' की दुकान नहीं है, तो आप [' 'A' की आवश्यकता नहीं है बिल्कुल] (http://is.gd/pbhLxP)। यह थोड़ा अजीब लगता है। – Shepmaster

+0

बिलकुल नहीं। यदि आप 'as_read() 'कई बार कॉल कर सकते हैं, तो आप i32 पर दो' और mut' के साथ समाप्त हो जाएंगे। आप देख सकते हैं कि अगर आप 'as_read' में अपरिवर्तनीय के रूप में पुनः जुड़ते हैं तो आप @ वाविन कोड का उपयोग कर सकते हैं: http://is.gd/Nt66hL यह शायद बेहतर उत्तर होगा। मैं अपना कोड –

+0

अपडेट करूंगा * आप i32 * पर दो और म्यूट के साथ समाप्त हो जाएंगे - मुझे याद आना चाहिए कि कैसे। चूंकि 'रीड' केवल एक अपरिवर्तनीय संदर्भ संग्रहीत करता है, इसलिए मैं म्यूटेबल -> अपरिवर्तनीय रेबरो स्वचालित रूप से होने की अपेक्षा करता हूं। इसके अलावा मैं ** पूरी तरह से ** '* * self.x' किया और यह काम नहीं किया। अब मैं पागल हो रहा हूँ। – Shepmaster

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