تخطَّ إلى المحتوى

range over func (iter.Seq)

المرور على دالة تكرارية مخصّصة range over func (iter.Seq)

منذ Go 1.23، range تقبل دالة تطابق توقيع iter.Seq[V] مباشرة، فتصبح كتابة تكرارات (iterators) مخصّصة قابلة للاستخدام بنفس صيغة range العادية.

حزمة iter تعرّف نوع الدالة Seq[V] بتوقيع func(yield func(V) bool). أي دالة تعيد iter.Seq[V] تصبح قابلة للتمرير مباشرة بعد range. داخل الدالة، تستدعي yield(v) لكل قيمة تريد تسليمها لجسم range؛ لو أعادت yield القيمة false — وهذا يحدث تلقائيًا لو المستدعي استخدم break — يجب التوقّف فورًا وعدم متابعة أي حساب إضافي.

إلى جانب iter.Seq[V] بقيمة واحدة، توجد iter.Seq2[K, V] بزوج قيم لكل خطوة (مفتاح وقيمة مثلًا)، تُستخدم بنفس صيغة range بمتغيّرين. هذا النمط هو ما تبنّته حزم stdlib مثل slices وmaps لإرجاع تسلسلات كسولة دون تخصيص شريحة كاملة بالذاكرة أولًا.

الصياغة

type Seq[V any] func(yield func(V) bool)

func Count(n int) iter.Seq[int] {
  return func(yield func(int) bool) {
    for i := 0; i < n; i++ {
      if !yield(i) {
        return
      }
    }
  }
}

📄 مثال

func Count(n int) iter.Seq[int] {
  return func(yield func(int) bool) {
    for i := 0; i < n; i++ {
      if !yield(i) {
        return
      }
    }
  }
}

for i := range Count(5) {
  if i == 3 {
    break   // يستدعي yield(false) داخليًا فيوقف Count فورًا
  }
  fmt.Println(i)   // 0 1 2
}

أهم النقاط

العنصرالوظيفة
iter.Seq[V]func(yield func(V) bool) — دالة تكرارية بقيمة واحدة لكل خطوة
iter.Seq2[K, V]نفس الفكرة بزوج قيم لكل خطوة، مثل مفتاح وقيمة
yield(v)استدعِها لكل قيمة تريد تسليمها؛ إعادتها false تعني توقّف فورًا (غالبًا بسبب break بجهة المستدعي)

💡 نصائح عملية

  • تحقّق دائمًا من القيمة المُعادة من yield وتوقّف فورًا إن كانت false — تجاهلها يهدر حسابًا لن يُستخدم أبدًا
  • استخدم هذا النمط لتسلسلات كبيرة أو لانهائية منطقيًا (سطور ملف ضخم، صفحات نتائج API) بدل بناء شريحة كاملة بالذاكرة أولًا

⚠️ أخطاء شائعة

  • كتابة دالة تكرارية تتجاهل القيمة المُعادة من yield وتكمل حلقتها الداخلية رغم طلب التوقّف — يهدر عملًا وقد يسبّب سلوكًا غير متوقّع
  • الخلط بين دالة عادية تعيد []T ودالة تكرارية تطابق iter.Seq[T] — الأولى تُستدعى مباشرة، والثانية تُستخدم فقط بعد range

خصائص ذات صلة

🎓 تريد فهم الصورة الكاملة خطوة بخطوة؟ ابدأ من مسار GO الكامل بالعربي.