मुझे लगता है कि कुछ और स्पष्ट करने के लिए कुछ है। संग्रह प्रकार, जैसे कि 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
।