هل يوجد foreach في Go؟ شرح خطوة بخطوة للمبتدئين

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

هل يوجد foreach في Go؟ دليل تعليمي خطوة بخطوة مع أمثلة

\n\n

إذا أتيت إلى Go من Python أو JavaScript أو PHP، فمن المحتمل أنك معتاد على foreach المختصر لتكرار المجموعات. والآن تكتب أول حلقة لك في Go وتتساءل: "أين هو foreach المفضل لدي؟ أليس موجودًا في Go؟"

\n\n

إجابة مختصرة: لا توجد كلمة مفتاحية مباشرة foreach في Go بالفعل. ولكن هناك شيء أكثر مرونة وقوة — بنية for range. في هذا الدليل التعليمي، سنشرح كيفية عمل التكرار في Go، ونعرض أمثلة كود حقيقية، ونقارنها بـ foreach المألوف من لغات أخرى.

\n\n

لماذا لا يوجد foreach في Go وما فائدة range؟

\n\n

Go لغة بسيطة. تجنب مبتكروها عمدًا تكرار البنى النحوية. بدلاً من إضافة كلمة مفتاحية منفصلة foreach، قاموا بتوسيع إمكانيات الحلقة الموجودة for. هكذا ظهر for range — أداة عالمية لاجتياز المصفوفات، والشرائح (slices)، والخرائط (maps)، والسلاسل النصية، وحتى القنوات (channels).

\n\n

إذا كنت تبحث عن بديل دقيق لـ foreach في Go، فهو هنا — for range.

\n\n

بناء جملة for range: شرح مبسط

\n\n

الهيكل الأساسي يبدو كالتالي:

\n\n
for index, value := range collection {\n    // جسم الحلقة\n}
\n\n

حيث:

\n
    \n
  • index — فهرس العنصر (للمصفوفات والشرائح) أو المفتاح (للخرائط).
  • \n
  • value — نسخة من قيمة العنصر.
  • \n
  • collection — مجموعتك (شريحة، مصفوفة، map، سلسلة نصية، أو قناة).
  • \n
\n\n

نقطة مهمة: value هي دائمًا نسخة من العنصر. إذا قمت بتغيير value داخل الحلقة، فلن يتغير العنصر الأصلي. لتغيير العناصر الأصلية، يجب الوصول إليها عبر الفهرس.

\n\n

مثال 1: اجتياز شريحة (slice) — بديل foreach في Go

\n\n

لنبدأ بالحالة الأكثر شيوعًا — تكرار عناصر الشريحة:

\n\n
package main\n\nimport "fmt"\n\nfunc main() {\n    fruits := []string{"تفاح", "موز", "كرز", "شمام"}\n\n    fmt.Println("تكرار الشريحة (بديل foreach):")\n    for index, fruit := range fruits {\n        fmt.Printf("الفهرس %d: %s\\n", index, fruit)\n    }\n}
\n\n

الإخراج:

\n
تكرار الشريحة (بديل foreach):\nالفهرس 0: تفاح\nالفهرس 1: موز\nالفهرس 2: كرز\nالفهرس 3: شمام
\n\n

إذا كنت تحتاج فقط إلى الفهرس (مثلاً لتغيير العناصر)، يمكنك حذف القيمة:

\n\n
for i := range fruits {\n    fruits[i] = "فاكهة: " + fruits[i]\n}
\n\n

وإذا كنت تحتاج فقط إلى القيم — استخدم الشرطة السفلية _:

\n\n
for _, fruit := range fruits {\n    fmt.Println(fruit)\n}
\n\n

مثال 2: اجتياز map — foreach كلاسيكي

\n\n

لا توجد طريقة أكثر أناقة لتكرار الخرائط في Go من for range:

\n\n
package main\n\nimport "fmt"\n\nfunc main() {\n    ages := map[string]int{\n        "آنا": 25,\n        "بوريس": 30,\n        "فيكتور": 35,\n    }\n\n    fmt.Println("تكرار map (foreach):")\n    for name, age := range ages {\n        fmt.Printf("%s: %d سنة\\n", name, age)\n    }\n}
\n\n

ترتيب اجتياز map في Go غير مضمون. إذا كنت بحاجة إلى ترتيب ثابت، قم بجمع المفاتيح في شريحة وفرزها.

\n\n

مثال 3: اجتياز سلسلة نصية — تكرار حرفي

\n\n

على عكس العديد من اللغات، for range في Go يتكرر عبر الرونات (رموز unicode) وليس عبر البايتات:

\n\n
package main\n\nimport "fmt"\n\nfunc main() {\n    text := "مرحبًا، Go!"\n\n    fmt.Println("اجتياز السلسلة النصية حرفًا حرفًا:")\n    for i, r := range text {\n        fmt.Printf("الموضع %d: الحرف '%c' (الرمز %U)\\n", i, r, r)\n    }\n}
\n\n

لاحظ: الفهرس i يشير إلى البايتة الأولى للرونة، وليس إلى الرقم التسلسلي للحرف. بالنسبة للسلاسل النصية ذات البايت الواحد

المدونات

توصيات الكتب