2014-07-20 13 views
9

मुझे structs के लिए जीवनकाल पैरामीटर के साथ काम करने में कोई समस्या है। मैं 100% निश्चित नहीं हूं कि समस्या का वर्णन कैसे करें, लेकिन मैंने एक मामूली मामला बनाया जो मेरी संकलन समय त्रुटि दिखाता है।जंग जीवनकाल त्रुटि कंक्रीट जीवनकाल की उम्मीद है लेकिन बाध्य जीवनकाल पाया

struct Ref; 

struct Container<'a> { 
    r : &'a Ref 
} 

struct ContainerB<'a> { 
    c : Container<'a> 
} 

trait ToC { 
    fn to_c<'a>(&self, r : &'a Ref) -> Container<'a>; 
} 

impl<'a> ToC for ContainerB<'a> { 
    fn to_c(&self, r : &'a Ref) -> Container<'a> { 
    self.c 
    } 
} 

त्रुटि मैं इस के साथ हो रही है

test.rs:16:3: 18:4 error: method `to_c` has an incompatible type for trait: expected concrete lifetime, but found bound lifetime parameter 'a 
test.rs:16 fn to_c(&self, r : &'a Ref) -> Container<'a> { 
test.rs:17  self.c 
test.rs:18 } 
test.rs:16:48: 18:4 note: expected concrete lifetime is the lifetime 'a as defined on the block at 16:47 
test.rs:16 fn to_c(&self, r : &'a Ref) -> Container<'a> { 
test.rs:17  self.c 
test.rs:18 } 
error: aborting due to previous error 

मैं कई रूपों की कोशिश की है और सिर्फ इस बात को संकलित करने के लिए नहीं मिल सकता है। मुझे यहां एक और पोस्ट मिली (How to fix: expected concrete lifetime, but found bound lifetime parameter) लेकिन इसे हल करने की बजाय समस्या के आसपास मिलती प्रतीत होती है। मैं वास्तव में नहीं देख सकता कि समस्या क्यों उत्पन्न होती है। & चाल के माध्यम से रेफरी पारित की जा रही है, तो इसे सही काम करना चाहिए?

कोई विचार? पूरी सहायताके लिए शुक्रिया।

उत्तर

13

चलो दो परिभाषाओं की तुलना करें। सबसे पहले, विशेषता विधि:

fn to_c<'a>(&self, r: &'a Ref) -> Container<'a>; 

और कार्यान्वयन:

fn to_c(&self, r: &'a Ref) -> Container<'a>; 

अंतर देखते हैं? उत्तरार्द्ध में <'a> नहीं है। <'a> को कहीं और निर्दिष्ट किया गया है; तथ्य यह है कि इसका एक ही नाम है इससे कोई फर्क नहीं पड़ता: यह पूरी तरह से एक अलग बात है।

कार्यात्मक रूप से, अपने विशेषता परिभाषा का कहना है कि वापस आ कंटेनर r से कुछ करने के लिए इसके अंदर एक संदर्भ होगा, लेकिन self से कुछ भी नहीं। यह विधि के अंदर self का उपयोग कर सकता है, लेकिन यह लौटाए गए मूल्य में इसके संदर्भों को संग्रहीत नहीं कर सकता है।

आपका विधि परिभाषा, तथापि, एक 'a कि r के जीवन काल और self को लौट Container (उस वस्तु ही है, नहीं संदर्भ-&'ρ₁ T<'ρ₂> में ρ₂ -यह एक सूक्ष्म लेकिन कभी कभी महत्वपूर्ण है करने के लिए, है बांध उपयोग कर रहा है अंतर), जबकि विशेषता परिभाषा का कोई कनेक्शन नहीं था।

कार्यान्वयन में विधि परिभाषा में <'a> डालने से मिलान करने के लिए दो को बनाया जा सकता है। लेकिन ध्यान रखें कि 'aContainerB<'a> से छायांकन कर रहा है; यह समान 'a है! हम इसे एक और नाम देने के लिए बेहतर हैं; सुविधा के लिए, मैं इसके विपरीत परिवर्तन कर देंगे, (या तो करना होगा) विधि के बजाय impl पर इसे बदलने:

impl<'b> ToC for ContainerB<'b> { 
    fn to_c<'a>(&self, r: &'a Ref) -> Container<'a> { 
     self.c 
    } 
} 

लेकिन अब बेशक आप एक समस्या है: वापसी मान की है Container<'b> टाइप करें (क्योंकि cContainerB<'b> में फ़ील्डहै), लेकिन आपके हस्ताक्षर Container<'a> (r से संदर्भ का उपयोग करते हुए कुछ self से नहीं) की मांग करता है।

एक तरीका जो इसे ठीक करेगा, &self के जीवनकाल को 'a दोनों विशेषता परिभाषा और कार्यान्वयन में निर्दिष्ट कर रहा है; कार्यान्वयन में, यह मांग करेगा कि 'b'a से अधिक या उसके बराबर था (इस तथ्य के आधार पर कि आपने जीवन भर 'a के साथ जीवनकाल 'b के साथ सफलतापूर्वक संदर्भ लिया है, और ऑब्जेक्ट को संदर्भ को उल्लिखित करना होगा) और इसलिए उप प्रकार के कारण ('a'b का उप प्रकार है) Container<'b> सुरक्षित रूप से Container<'a> पर ले जाया जाएगा।

जीवन भर के मामलों के इस प्रकार के बारे में सोचना मुश्किल होता है जब आप उनसे परिचित नहीं होते हैं; लेकिन समय में वे काफी प्राकृतिक हो जाते हैं।

+1

एक और फिक्स 'टीआईसी <'a> {fn to_c (& self, r: & 'a ref) -> कंटेनर <'a>; } '। – huon

+0

ओह हाँ, और फिर कंटेनर'के लिए' impl <'a> TOC <'a> '। –

+0

यह निश्चित रूप से बहुत कुछ मदद करता है और मेरे कुछ गलत विचारों को ठीक करता है (उदाहरण के लिए जीवनकाल छायांकन)! धन्यवाद। यह इस मामले को 100% तय करता है, लेकिन मैं इसे दूसरे पर लागू नहीं कर सकता। मैंने यहां उस प्रश्न को लिखा: http://stackoverflow.com/questions/24853111/rust-lifetime-error-expected-concrete-lifetime-part-2) – luke

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