test
समारोह है कि प्रकार F
लागू करता Foo<'a>
की आवश्यकता है। 'a
एक जीवनकाल पैरामीटर है जो फ़ंक्शन को पास कर दिया गया है। लाइफटाइम पैरामीटर हमेशा जीवनकाल का प्रतिनिधित्व करते हैं जो फ़ंक्शन कॉल से अधिक समय तक जीवित रहते हैं - क्योंकि कोई भी कॉलर कम जीवनकाल के साथ संदर्भ प्रदान नहीं कर सकता है; आप स्थानीय चर के संदर्भ को से दूसरे फ़ंक्शन से कैसे पारित कर सकते हैं? -, और उधार जांच (जो एक समारोह के लिए स्थानीय है) के प्रयोजनों के लिए, संकलक मानता है कि उधार पूरे समारोह कॉल को कवर करता है।
इसलिए, जब आप Foo::new
करने के लिए कॉल से F
का एक उदाहरण बनाने के लिए, आप एक वस्तु है कि जीवन भर 'a
के साथ कुछ उधार लेता है, एक जीवन भर है कि पूरे समारोह कॉल को शामिल किया गया पैदा करते हैं।
यह समझना महत्वपूर्ण है कि जब आप test::<FooS>
फोन, संकलक वास्तव में FooS<'a>
के लिए एक जीवन भर के पैरामीटर में भर जाता है के लिए महत्वपूर्ण है, तो आप test::<FooS<'a>>
, जहां 'a
(क्षेत्र है कि बयान है कि समारोह कॉल शामिल शामिल किया गया है, क्योंकि &mut a
है बुला अंत एक अस्थायी अभिव्यक्ति)। इसलिए, संकलक सोचता है कि FooS
जो test
में बनाया जाएगा, test
पर कॉल के साथ कथन के अंत तक कुछ उधार लेगा! nongeneric संस्करण के साथ
आइए इसके विपरीत इस:
let mut foo = FooS {data: data};
इस संस्करण में, संकलक test
में FooS<'a>
के लिए एक ठोस जीवन चुनता है, बल्कि main
की तुलना में, तो यह ब्लॉक प्रत्यय छोर से विस्तार का चयन करेंगे ब्लॉक के अंत में let
कथन का, जिसका अर्थ है कि data
का अगला उधार ओवरलैप नहीं होता है और कोई संघर्ष नहीं होता है।
क्या आप वास्तव में चाहते हैं कि F
कुछ जीवन 'x
कि 'a
तुलना में कम है के लिए लागू Foo<'x>
, और सबसे महत्वपूर्ण यह है कि जीवन भर के समारोह में मौजूद क्षेत्र में होना चाहिए, न कि एक enclosing एक 'a
की तरह है।
इस समस्या का जंग का वर्तमान समाधान उच्च रैंकिंग विशेषता सीमा है। यह इस तरह दिखता है:
fn test<'a, F>(data: &'a mut u32)
where F: for<'x> Foo<'x>
{
{
let mut foo: F = Foo::new(data);
foo.apply();
}
println!("{:?}", data);
}
शब्दों में, इसका मतलब है प्रकार F
हर संभव 'x
के लिए Foo<'x>
को लागू करना चाहिए।
test
के इस संस्करण में अपने दम पर संकलित करते हैं, हम वास्तव में एक प्रकार है कि क्योंकि हर संभव जीवन 'a
के लिए इस बाधा को पूरा, आपूर्ति नहीं कर सकते हैं, वहाँ एक अलग प्रकार FooS<'a>
कि केवल लागू करता Foo<'a>
है।यदि FooS
था कोई जीवन भर पैरामीटर और FooS
के लिए Foo
की impl इस तरह देखा:
impl<'a> Foo<'a> for FooS {
तो यह ठीक हो जाएगा के बाद से वहाँ एक ही प्रकार FooS
कि हर संभव जीवन 'a
के लिए Foo<'a>
लागू करता है।
बेशक, आप FooS
पर जीवनकाल पैरामीटर को नहीं हटा सकते हैं, क्योंकि इसमें उधारकर्ता पॉइंटर होता है। इस समस्या का उचित समाधान एक ऐसी सुविधा है जो जंग के पास अभी तक नहीं है: एक फ़ंक्शन के लिए सामान्य पैरामीटर के रूप में एक प्रकार के कन्स्ट्रक्टर (पूरी तरह से निर्मित प्रकार के बजाय) को पास करने की क्षमता। इस क्षमता के साथ, हम test
पर FooS
के साथ कॉल कर सकते हैं, एक प्रकार का कन्स्ट्रक्टर जिसे एक ठोस प्रकार का उत्पादन करने के लिए जीवनकाल पैरामीटर की आवश्यकता होती है, कॉल साइट पर ठोस जीवनकाल निर्दिष्ट किए बिना, और कॉलर अपने जीवनकाल की आपूर्ति करने में सक्षम होगा।
https://play.rust-lang.org/?gist=dabe17d66a14e72c2ca67e064ca26601&version=nightly&backtrace=0 काम करता है। तो ... – Jacob
फिर भी, यह एक बग प्रतीत होता है। विस्तृत उत्तर के लिए – JDemler