जंग में, मैं एक उत्परिवर्तनीय पुनरावृत्ति कैसे बनाऊं? [डुप्लीकेट]
जब मैं सुरक्षित जंग में एक उत्परिवर्तनीय पुनरावृत्ति बनाने की कोशिश कर रहा हूँ तो मुझे जीवन भर के लिए कठिनाई हो रही है।
यहाँ मैं अपनी समस्या को कम कर दिया है:
struct DataStruct<T> {
inner: Box<[T]>,
}
pub struct IterMut<'a, T> {
obj: &'a mut DataStruct<T>,
cursor: usize,
}
impl<T> DataStruct<T> {
fn iter_mut(&mut self) -> IterMut<T> {
IterMut { obj: self, cursor: 0 }
}
}
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item> {
let i = f(self.cursor);
self.cursor += 1;
self.obj.inner.get_mut(i)
}
}
fn f(i: usize) -> usize {
// some permutation of i
}
मेरी संरचना DataStruct
कभी नहीं बदलेगी, लेकिन मुझे भीतर संग्रहीत तत्वों की सामग्री को बदलने में सक्षम होने की आवश्यकता है। उदाहरण के लिए,
let mut ds = DataStruct{ inner: vec![1,2,3].into_boxed_slice() };
for x in ds {
*x += 1;
}
संकलक मुझे उस संदर्भ के लिए संघर्षशील जीवनकाल के बारे में एक त्रुटि दे रहा है जो मैं वापस लौटने की कोशिश कर रहा हूं। जीवनकाल यह पाता है कि मुझे उम्मीद नहीं है कि यह next(&mut self)
कार्यक्षेत्र है।
अगर मैं आजीवन इस पर टिप्पणी करने की कोशिश करता हूं next()
, तो संकलक, इसके बजाय, मुझे बताता है कि मैंने Iterator विशेषता को संतुष्ट नहीं किया है। क्या यह सुरक्षित जंग में है?
यहाँ त्रुटि है:
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> src/iter_mut.rs:25:24
|
25 | self.obj.inner.get_mut(i)
| ^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 22:5...
--> src/iter_mut.rs:22:5
|
22 | / fn next(&mut self) -> Option<Self::Item> {
23 | | let i = self.cursor;
24 | | self.cursor += 1;
25 | | self.obj.inner.get_mut(i)
26 | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/iter_mut.rs:25:9
|
25 | self.obj.inner.get_mut(i)
| ^^^^^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 19:6...
--> src/iter_mut.rs:19:6
|
19 | impl<'a, T> Iterator for IterMut<'a, T> {
| ^^
note: ...so that the types are compatible
--> src/iter_mut.rs:22:46
|
22 | fn next(&mut self) -> Option<Self::Item> {
| ______________________________________________^
23 | | let i = self.cursor;
24 | | self.cursor += 1;
25 | | self.obj.inner.get_mut(i)
26 | | }
| |_____^
= note: expected `std::iter::Iterator`
found `std::iter::Iterator`
संपादन :
- परिवर्तन को लागू करना
next()
ताकि पुनरावृत्ति क्रम मूल अनुक्रम का क्रमपरिवर्तन हो।
जवाब
उधार लेने वाला चेकर यह साबित करने में असमर्थ है कि बाद की कॉल next()
उसी डेटा तक नहीं पहुँच सकती। यह समस्या क्यों है, इसका कारण यह है कि उधारकर्ता का जीवनकाल पुनरावृत्त के जीवन की अवधि के लिए है, इसलिए यह साबित नहीं कर सकता है कि एक ही समय में एक ही डेटा के दो परस्पर संदर्भ नहीं होंगे।
वास्तव में असुरक्षित कोड के बिना इसे हल करने का कोई तरीका नहीं है - या अपनी डेटा संरचनाओं को बदलना। आप ऐसा कर सकते हैं slice::split_at_mut
, लेकिन मूल डेटा को म्यूट नहीं किया जा सकता , लेकिन आपको इसे असुरक्षित कोड में वैसे भी लागू करना होगा। असुरक्षित कार्यान्वयन कुछ इस तरह दिख सकता है:
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item> {
let i = self.cursor;
self.cursor += 1;
if i < self.obj.inner.len() {
let ptr = self.obj.inner.as_mut_ptr();
unsafe {
Some(&mut *ptr.add(i))
}
} else {
None
}
}
}