मैं एक समस्या यह है कि में सरल में भाग निम्नलिखित:क्या मैं एक इटरेटर लिख सकता हूं जो खुद को बदलता है और फिर खुद में एक संदर्भ उत्पन्न करता है?
struct MyIter {
vec: Vec<i8>,
}
fn fill_with_useful_data(v: &mut Vec<i8>) {
/* ... */
}
impl<'a> Iterator for MyIter {
type Item = &'a [i8];
fn next(&mut self) -> Option<&'a [i8]> {
fill_with_useful_data(&mut self.vec);
Some(&self.vec)
}
}
fn main() {
for slice in (MyIter { vec: Vec::new() }) {
println!("{}", slice);
}
}
यह त्रुटि उत्पन्न करता है:
error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
--> src/main.rs:9:6
|
9 | impl<'a> Iterator for MyIter {
| ^^ unconstrained lifetime parameter
विचार है कि इटरेटर काम का एक समूह है कि अपने क्षेत्र में और कम से दर्शाता करता है प्रत्येक चरण, यह कॉलिंग कोड में खुद को संदर्भ देता है। इस मामले में मैं इसे संदर्भ के बजाय राज्य की एक प्रति प्राप्त करने के रूप में मॉडल कर सकता हूं, लेकिन आइए दिखाएं कि यह संभव नहीं है या केवल असुविधाजनक महंगा है।
Intuitively यह एक समस्या है क्योंकि उधार चेकर सुनिश्चित कर सकते हैं कि .next()
फिर से, जबकि सामने आए संदर्भ अभी भी इटरेटर के राज्य निरीक्षण करने के लिए इस्तेमाल किया जा सकता नहीं बुलाया जाता है नहीं होना चाहिए, लेकिन Iterator
विशेषता के लिए प्रदान करने के लिए प्रतीत नहीं होता उस तरह की चीज सीधे। यहां तक कि कुछ क्रमिकताओं के साथ ही इटेटरेटर में वेक्टर के संदर्भ में या केवल इटेटरेटर को संदर्भ में या कुछ प्रकार के जीवन में प्राप्त करने के लिए कुछ बनाने के लिए, मुझे उधार चेकर के पीछे कुछ भी नहीं मिल सकता है।
मैंने ब्लॉग पोस्ट पर "Iterators yielding mutable references" पढ़ा लेकिन मुझे यकीन नहीं है कि यह मेरी समस्या पर लागू होता है या नहीं, जिसमें परिवर्तनीय संदर्भ शामिल नहीं हैं।
ठीक है, मैंने अभी 'इटरेटर' को लागू करना बंद कर दिया है और मैक्रो के साथ अपना स्वयं का लूप बनाया है। मैंने नहीं सोचा था कि कैसे .collect() 'काम नहीं करेगा। – ben
यह ट्रैवर्सल के लिए भी अच्छा है जहां आप 'for' loop का उपयोग नहीं कर सकते: 'जबकि कुछ (तत्व) = iter.next() {...' – bluss
भविष्य के संदर्भ के लिए, इस प्रकार के इटरेटर ('fn अगला (और 'स्वयं) ') को अक्सर * स्ट्रीमिंग इटरेटर * के रूप में जाना जाता है। चर्चाओं के कुछ नमूने [1] (https://users.rust-lang.org/t/returning-borrowed-values-from-an-iterator/1096), [2] (https://www.reddit.com/आर/जंग/टिप्पणियां/2t1rxx/more_general_iterator_trait /), और एक [क्रेट जो इसके रूप को लागू करता है] (https://github.com/sfackler/streaming-iterator)। – Shepmaster