एकाधिक उत्परिवर्तनीय संदर्भों के कारण किसी संरचना के सदस्य को खुद को सौंपना असंभव हो जाता है? [डुप्लिकेट]
मैं उधार लेने में सक्षम नहीं हूं जहां मुझे लगा कि मैं कर सकता हूं। मैंने इस मामले में समस्या को कम किया:
struct A<'a> {
borrow: &'a mut u8,
}
fn does_nothing<'b, 'c>(a: &'b mut A<'c>) {
a.borrow = a.borrow;
}
error[E0623]: lifetime mismatch
--> src/lib.rs:6:16
|
5 | fn does_nothing<'b, 'c>(a: &'b mut A<'c>) {
| -------------
| |
| these two types are declared with different lifetimes...
6 | a.borrow = a.borrow;
| ^^^^^^^^ ...but data from `a` flows into `a` here
ऐसा लगता है कि a.borrow
का चौराहा है 'b
और 'c
इसलिए अभी भी जीवन भर की गारंटी नहीं दी जा सकती है 'c
।
मुझे इससे कोई वास्तविक समस्या नहीं है और दोनों जीवन भर एक ही बनाकर इसके चारों ओर काम कर सकते हैं, लेकिन यह चेक उधार क्यों नहीं लेता है?
ऐसा लगता है कि इस मुद्दे को दिखाने के लिए संरचनाएं महत्वहीन हैं और दोहरे उधार इसे आसानी से दिखाते हैं।
मेरे तीन कार्य हैं जो काफी हद तक समान हैं, लेकिन मुझे यह जानने में परेशानी होगी कि कौन-सा संकलन है और कौन-सा संकलन गैर-संकलनकर्ताओं को देगा।
सरल सामान्य कार्य:
fn only_borrow<T>(a: &mut T) {
*a = *a;
}
परिणाम में त्रुटि:
error[E0507]: cannot move out of `*a` which is behind a mutable reference
--> src/lib.rs:2:10
|
2 | *a = *a;
| ^^ move occurs because `*a` has type `T`, which does not implement the `Copy` trait
अप्रत्यक्ष के अतिरिक्त स्तर को शामिल करने से त्रुटि में परिवर्तन होता है
fn only_borrow_double<T>(a: &mut &mut T) {
*a = *a;
}
error[E0623]: lifetime mismatch
--> src/lib.rs:2:10
|
1 | fn only_borrow_double<T>(a: &mut &mut T) {
| -----------
| |
| these two types are declared with different lifetimes...
2 | *a = *a;
| ^^ ...but data from `a` flows into `a` here
निहित जीवनकाल से दूर करने से त्रुटि ठीक हो सकती है:
fn working_double<'b, T>(a: &'b mut &'b mut T) {
*a = *a;
}
जवाब
आपको अपने जीवन काल पर एक नज़र डालनी होगी 'b
और 'c
:
&'b mut ...
इसका मतलब है कि आपके पास एक संदर्भ है जो "समय" के लिए जीवित और मान्य है'b
।A<'c>
इसका मतलब है कि आपके पास एक ऐसी वस्तु है जो जीवित है और जिसके लिए वैध है'c
।
आपके पास जो नहीं है वह इन दो जन्मों के बीच एक विशिष्ट संबंध है। केवल एक चीज जो कंपाइलर काट सकता है वह यह है कि चूंकि A<'c>
पीछे एक है &'b
, तो 'c
उसे आउटलाइव करना चाहिए 'b
, यानी जब भी 'b
वैध हो, ऐसा है 'c
। हालांकि, महत्वपूर्ण रूप से, अन्य तरीके से नहीं।
आपको बताएंगे कि के रूप में, संकलक की आवश्यकता है 'b
और 'c
एक ही जीवन भर किया जाना है। ऐसा क्यों है?
आइए हम अपनी संभावनाओं पर एक नज़र डालें:
'c
और'b
इसका कोई संबंध नहीं है: यह देखना आसान है कि किसी भी संबंध के बिना, संकलक इस बात की गारंटी नहीं दे सकता है कि इसमें क्या डाला गया हैA.borrow
और इस तरह यह अनुमति नहीं देगा।'c
कड़ाई से उल्लिखित'b
, यानी, कुछ स्थानों'c
को मान्य'b
नहीं है: जीवनकाल
a.borrow = a.borrow
काa
उपयोग करने का एक पुनर्जन्म बन जाता है'b
। यह उत्तर बताता है कि ऐसा क्यों होता है । हालांकि, इसका मतलब है किa
अब'b
जीवनकाल पर निर्भर है , जो कि कुछ समय केa
लिए मान्य नहीं है (चूंकिa
जीवनकाल है'c
)। यह त्रुटि देता है।'b
कड़ाई से उल्लिखित'c
: यदि हमारे पास यह संबंध था, तो यह काम कर सकता है। रिबोर मान्य होगा, क्योंकि हमें एक "जीवन भर" ('b
) की तुलना में हमने ('c
) के लिए कहा है । हालांकि, हम पहले से ही'c: 'b
पर्दे के पीछे कंपाइलर से अनुमान लगा चुके हैं । इसलिए, इस जीवनकाल को जोड़ने का मतलब है कि दो जीवनकाल समान हो गए और हम फिर से वहीं हैं जहाँ हमने शुरू किया था:
struct A<'a> {
borrow: &'a mut u8,
}
/// We add the relation 'b: 'c
fn does_nothing<'b: 'c, 'c>(a: &'b mut A<'c>) {
a.borrow = a.borrow;
}