Go ضد Python: هل يوجد في Go بناء "if x in"؟

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

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

ابدأ الدورة

مقدمة: لماذا يشتاق مبرمجو Python إلى "in" في Go؟

\n\n

إذا أتيت إلى Go من عالم Python، فبالتأكيد تتذكر هذا السطر السحري: if "banana" in fruits:. قصير، أنيق، قابل للقراءة. ثم تفتح Go وتسأل نفسك: "هل يحتوي Go على بناء 'if x in' مشابه لـ Python؟" — هذا هو بالضبط السؤال الأكثر شيوعًا على Stack Overflow، الذي جمع آلاف المشاهدات.

\n\n

ملخص سريع: لا يوجد سكر نحوي مباشر مثل in في Go. لكن هذا لا يعني أن المهمة غير قابلة للحل أو صعبة الحل. على العكس، في Go هناك عدة طرق اصطلاحية للتحقق من الوجود، كل منها فعال وجميل بطريقته الخاصة.

\n\n

في هذه المقالة، سنستعرض:

\n
    \n
  • لماذا لا يوجد in في Go وكيف أثرت فلسفة اللغة على ذلك؛
  • \n
  • كيفية التحقق من وجود عنصر في الشريحة (slice) (بما في ذلك استخدام الدالة الجديدة slices.Contains)؛
  • \n
  • كيف يعمل البحث في الخريطة (map) (ملخص سريع: هذه هي أسرع طريقة)؛
  • \n
  • البحث عن سلسلة فرعية في سلسلة نصية باستخدام strings.Contains؛
  • \n
  • كتابة دالة تغليف عامة خاصة بنا لأسلوب "يشبه Python"؛
  • \n
  • مقارنة أداء الطرق المختلفة.
  • \n
\n\n

لماذا لا تريد Go "if x in"؟

\n\n

Go لغة بسيطة. مبتكروها (روب بايك، كين تومسون، روب غريزمر) تجنبوا عمدًا إثقال بناء الجملة. بدلاً من إضافة كلمة مفتاحية in، اقترحوا استخدام حلقات صريحة وتراكيب مدمجة.

\n\n

هذا ليس عيبًا، بل ميزة: ترى دائمًا ما يحدث بالضبط. على سبيل المثال، بالنسبة للخريطة، بناء الجملة value, ok := myMap[key] لا يمنحك فقط التحقق من الوجود، بل أيضًا القيمة نفسها — وهذا أقوى من مجرد قيمة منطقية True/False.

\n\n

الطريقة 1: البحث في الشريحة (الطريقة التقليدية)

\n\n

السيناريو الأكثر شيوعًا. لنفترض أن لديك شريحة من السلاسل النصية، وتحتاج إلى التحقق مما إذا كانت تحتوي على "Go".

\n\n

قبل إصدار Go 1.21، كان عليك كتابة حلقة يدويًا:

\n\n
package main\n\nimport "fmt"\n\nfunc contains(slice []string, target string) bool {\n    for _, v := range slice {\n        if v == target {\n            return true\n        }\n    }\n    return false\n}\n\nfunc main() {\n    languages := []string{"Python", "Java", "Go", "Rust"}\n    if contains(languages, "Go") {\n        fmt.Println("تم العثور على Go!")\n    }\n}\n
\n\n

هذا الكود هو Go اصطلاحي. إنه صريح وسريع ومفهوم. بالنسبة للشرائح الصغيرة (حتى 1000 عنصر)، يعمل هذا البحث الخطي بشكل ممتاز.

\n\n

الطريقة 1.1: استخدام slices.Contains (Go 1.21+)

\n\n

بدءًا من إصدار Go 1.21 (صدر في أغسطس 2023)، ظهرت حزمة slices في المكتبة القياسية مع دالة جاهزة Contains. الآن أصبح كودك موجزًا تقريبًا مثل Python:

\n\n
package main\n\nimport (\n    "fmt"\n    "slices"\n)\n\nfunc main() {\n    languages := []string{"Python", "Java", "Go", "Rust"}\n    if slices.Contains(languages, "Go") {\n        fmt.Println("تم العثور على Go! (عبر slices.Contains)")\n    }\n}\n
\n\n

هام: slices.Contains هي دالة عامة (generic). تعمل مع أي نوع يدعم عامل == (سلاسل نصية، أرقام، قيم منطقية، هياكل بدون شرائح/خرائط داخلها).

\n\n

الطريقة 2: البحث في الخريطة — ملك الأداء

\n\n

في Python، تستخدم in للقواميس، وهذا وقت ثابت O(1). في Go نفس الشيء، لكن بناء الجملة مختلف:

\n\n
package main\n\nimport "fmt"\n\nfunc main() {\n    // إنشاء خريطة كمجموعة (set)\n    fruits := map[string]bool{\n        "apple":  true,\n        "banana": true,\n        "cherry": true,\n    }\n\n    if fruits["banana"] {\n        fmt.Println("الموجودة موجودة!")\n    }\n\n    // الطريقة الأصح — مع التحقق من ok\n    if _, ok := fruits["orange"]; ok                

المدونات

توصيات الكتب