আমি মনে করি আরও কিছু স্পষ্ট করার মতো কিছু আছে। সংগ্রহের ধরণের, যেমন 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
।