المكررات المخصصة
طبّق Iterator
المكررات المخصصة درس مجاني في Learn Rust Coding على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Learn Rust Coding، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Learn Rust Coding 4 دروس في المجموع.
أنشئ مكرّرك الخاص
لست مقيدًا بالمكرّرات المضمّنة. فعند تنفيذ السمة Iterator لنوعك الخاص، سيحصل على كل المحوّلات والمستهلِكات تلقائيًا.
وكل ما عليك توفيره هو نوع Item وطريقة next.
بنية عدّاد
ابدأ ببنية تحتفظ بحالة المكرّر. لا يحتاج العدّاد البسيط إلا إلى قيمة حالية.
struct Counter {
count: u32,
}
fn main() {
let c = Counter { count: 0 };
println!("start at {}", c.count);
}تنفيذ next
نفّذ Iterator للبنية. عيّن type Item، ثم اكتب next لتقدّم الحالة وتُرجع Some إلى أن يتحقق شرط التوقف، ثم تُرجع None.
struct Counter { count: u32 }
impl Iterator for Counter {
type Item = u32;
fn next(&mut self) -> Option<u32> {
if self.count < 5 {
self.count += 1;
Some(self.count)
} else {
None
}
}
}
fn main() {
let mut c = Counter { count: 0 };
println!("{:?}", c.next());
println!("{:?}", c.next());
}استخدامه في حلقة for
بمجرد وجود next، يعمل نوعك في حلقة for مثل أي مكرّر قياسي.
struct Counter { count: u32 }
impl Iterator for Counter {
type Item = u32;
fn next(&mut self) -> Option<u32> {
if self.count < 5 { self.count += 1; Some(self.count) } else { None }
}
}
fn main() {
for n in (Counter { count: 0 }) {
print!("{} ", n);
}
println!();
}المحوّلات والمستهلِكات المجانية
لأنك نفّذت طريقة واحدة، أصبحت مجموعة أدوات المكرّر كاملة متاحة الآن. نجمع هنا مربعات قيمتي العدّاد المقترنتين.
struct Counter { count: u32 }
impl Iterator for Counter {
type Item = u32;
fn next(&mut self) -> Option<u32> {
if self.count < 5 { self.count += 1; Some(self.count) } else { None }
}
}
fn main() {
let total: u32 = Counter { count: 0 }.map(|x| x * 2).sum();
println!("{}", total);
}طريقة بنّاء
أضف دالة new حتى لا يضطر المستخدمون إلى الوصول إلى الحقول الداخلية. هذا أنظف، ويسمح لك بإبقاء الحقل خاصًا.
struct Counter { count: u32 }
impl Counter {
fn new() -> Counter { Counter { count: 0 } }
}
impl Iterator for Counter {
type Item = u32;
fn next(&mut self) -> Option<u32> {
if self.count < 3 { self.count += 1; Some(self.count) } else { None }
}
}
fn main() {
let v: Vec<u32> = Counter::new().collect();
println!("{:?}", v);
}مكرّر فيبوناتشي
يمكن للمكرّرات الاحتفاظ بحالة أكثر تعقيدًا. يحتفظ مولّد فيبوناتشي بآخر قيمتين ويحدّثهما عند كل استدعاء لـ next.
struct Fib { a: u64, b: u64 }
impl Iterator for Fib {
type Item = u64;
fn next(&mut self) -> Option<u64> {
let current = self.a;
self.a = self.b;
self.b = current + self.b;
Some(current)
}
}
fn main() {
let fib = Fib { a: 0, b: 1 };
let seq: Vec<u64> = fib.take(8).collect();
println!("{:?}", seq);
}المكرّرات اللانهائية مناسبة
لا يُرجع مكرّر فيبوناتشي None أبدًا — فهو لانهائي. وهذا آمن لأن الكسل يعني إنتاج القيم عند الطلب فقط. استخدم take لوضع حد له.
struct Fib { a: u64, b: u64 }
impl Iterator for Fib {
type Item = u64;
fn next(&mut self) -> Option<u64> {
let c = self.a;
self.a = self.b;
self.b = c + self.b;
Some(c)
}
}
fn main() {
let big = Fib { a: 0, b: 1 }.nth(20);
println!("{:?}", big);
}التكرار على نوع مغلِّف
غالبًا ما تنفّذ Iterator على بنية مساعدة تستعير بياناتك. يُرجع محرّك الخطوات هنا كل رقم ثانٍ من نطاق مخزّن بداخله.
struct EvenUpTo { current: u32, max: u32 }
impl Iterator for EvenUpTo {
type Item = u32;
fn next(&mut self) -> Option<u32> {
if self.current > self.max { return None; }
let value = self.current;
self.current += 2;
Some(value)
}
}
fn main() {
let evens: Vec<u32> = (EvenUpTo { current: 0, max: 10 }).collect();
println!("{:?}", evens);
}لماذا ننشئ مكرّرات مخصصة؟
تتيح لك المكرّرات المخصصة بثّ القيم من دون تخصيص مجموعة كاملة، ونمذجة تسلسلات لانهائية أو محسوبة، وتوفير واجهة مألوفة قابلة للتركيب للمتصلين بها.
وتفتح طريقة next صغيرة واحدة المجال أمام المنظومة بأكملها.
نصائح للتصميم
أبقِ حالتك بسيطة، وأرجع None مرة واحدة بالضبط عند النهاية (أو لا ترجعه أبدًا في المكرّرات اللانهائية)، وتجنب تنفيذ أعمال ثقيلة داخل next حتى يظل الكسل قليل التكلفة.
تحقق سريع
تنفيذ سمة Iterator.
مراجعة
أنشأتَ مكرّرات مخصصة:
- احتفظ بالحالة في بنية، ثم استخدم
impl Iterator - عرّف
type Itemواكتبnext - تحصل فورًا على المحوّلات والمستهلِكات مجانًا
- يمكن أن تكون المكرّرات منتهية أو لانهائية؛ استخدم
takeلوضع حد للمكرّرات اللانهائية
الأسئلة الشائعة
هل درس «المكررات المخصصة» مجاني؟
نعم — نص درس «المكررات المخصصة» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Learn Rust Coding، انتقل إلى CoddyKit PRO. تتضمن دورة Learn Rust Coding 4 دروس في المجموع.
ماذا ستتعلم في «المكررات المخصصة»؟
طبّق Iterator تتمرن على Learn Rust Coding مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Learn Rust Coding؟
لا تُشترط خبرة سابقة. Learn Rust Coding على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.
كم من الوقت يستغرق درس «المكررات المخصصة»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Learn Rust Coding هذا؟
نعم. كل درس في Learn Rust Coding يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- سمة Iterator
- map وfilter وcollect
- المهايئات والمستهلكات
- المكررات المخصصة