मुझे लगता है कि कुछ और स्पष्ट करने के लिए कुछ है। संग्रह प्रकार, जैसे कि Vec<T>और VecDeque<T>, into_iterविधि है कि पैदावार Tक्योंकि वे लागू करते हैं IntoIterator<Item=T>। एक प्रकार का निर्माण करने के लिए हमें रोकने के लिए कुछ भी नहीं है Foo<T>अगर जो अधिक पुनरावृत्त है, तो यह Tएक और प्रकार नहीं बल्कि उपज देगा U। वह है, Foo<T>लागू होना IntoIterator<Item=U>।
वास्तव में, कुछ उदाहरण हैं std: &Path लागू करना IntoIterator<Item=&OsStr> और &UnixListener लागू करना IntoIterator<Item=Result<UnixStream>> ।
into_iterऔर के बीच का अंतरiter
into_iterऔर के बीच के अंतर पर मूल प्रश्न पर वापस जाएं iter। जैसा कि अन्य ने बताया है, अंतर यह है कि into_iterएक आवश्यक विधि है, IntoIteratorजिसमें किसी भी प्रकार का निर्दिष्ट पैदावार मिल सकती है IntoIterator::Item। आमतौर पर, यदि एक प्रकार का IntoIterator<Item=I>अधिवेशन, इसके अधिवेशन के भी दो तदर्थ तरीके हैं: iterऔर iter_mutजो क्रमशः उपज &Iऔर &mut I।
इसका तात्पर्य यह है कि हम एक ऐसा फंक्शन बना सकते हैं जिसमें एक प्रकार मिलता है जिसमें एक into_iterविधि है (यानी यह एक चलने योग्य है) एक ट्रेस बाउंड का उपयोग करके:
fn process_iterable<I: IntoIterator>(iterable: I) {
for item in iterable {
// ...
}
}
हालांकि, हम नहीं कर सकते हैं * एक विशेषता है करने के लिए एक प्रकार की आवश्यकता होती है करने के लिए बाध्य का उपयोग iterविधि या iter_mut, विधि, क्योंकि वे सिर्फ सम्मेलनों कर रहे हैं। हम कह सकते हैं कि into_iterअधिक व्यापक रूप से प्रयोग करने योग्य iterया से अधिक है iter_mut।
करने के लिए विकल्प iterऔरiter_mut
निरीक्षण करने के लिए एक और दिलचस्प यह iterहै कि पैदावार करने वाले इट्रेटर प्राप्त करने का एकमात्र तरीका नहीं है &T। परंपरा के मुताबिक (फिर), संग्रह प्रकार SomeCollection<T>में stdजो है iterविधि को भी अपने अपरिवर्तनीय संदर्भ प्रकार &SomeCollection<T>लागू IntoIterator<Item=&T>। उदाहरण के लिए, &Vec<T> लागू होता है IntoIterator<Item=&T> , इसलिए यह हमें इसे पुन &Vec<T>: व्यवस्थित करने में सक्षम बनाता है :
let v = vec![1, 2];
// Below is equivalent to: `for item in v.iter() {`
for item in &v {
println!("{}", item);
}
यदि उस दोनों में v.iter()समान है , तो &vलागू IntoIterator<Item=&T>क्यों होता है, तो दोनों क्यों प्रदान करते हैं? यह एर्गोनॉमिक्स के लिए है। में forछोरों, यह उपयोग करने के लिए एक सा अधिक संक्षिप्त है &vकी तुलना में v.iter(); लेकिन अन्य मामलों में, v.iter()की तुलना में बहुत स्पष्ट है (&v).into_iter():
let v = vec![1, 2];
let a: Vec<i32> = v.iter().map(|x| x * x).collect();
// Although above and below are equivalent, above is a lot clearer than below.
let b: Vec<i32> = (&v).into_iter().map(|x| x * x).collect();
इसी तरह, forछोरों में, v.iter_mut()इसके साथ प्रतिस्थापित किया जा सकता है &mut v:
let mut v = vec![1, 2];
// Below is equivalent to: `for item in v.iter_mut() {`
for item in &mut v {
*item *= 2;
}
जब एक प्रकार के लिए प्रदान करने (लागू करने) into_iterऔर iterतरीके
यदि टाइप का केवल एक ही "तरीका" है जो इसे खत्म कर देता है, तो हमें दोनों को लागू करना चाहिए। हालांकि, अगर दो तरीके या अधिक हैं, तो इसे खत्म किया जा सकता है, हमें इसके बजाय प्रत्येक तरीके के लिए एक तदर्थ विधि प्रदान करनी चाहिए।
उदाहरण के लिए, Stringन तो प्रदान करता है और न into_iterही iterक्योंकि इसे पुनरावृत्त करने के दो तरीके हैं: बाइट्स में अपने प्रतिनिधित्व को पुनरावृत्त करना या वर्णों में इसके प्रतिनिधित्व को पुनरावृत्त करना। इसके बजाय, यह दो तरीके प्रदान करता है: bytesबाइट्स charsके पुनरावृत्ति के लिए और वर्णों को पुनरावृत्त करने के लिए, iterविधि के विकल्प के रूप में ।
* ठीक है, तकनीकी रूप से हम इसे एक विशेषता बनाकर कर सकते हैं। लेकिन तब हमें implउस प्रकार के गुण की आवश्यकता होती है जिसका हम उपयोग करना चाहते हैं। इस बीच, stdपहले से ही लागू कई प्रकार IntoIterator।