التحقق من وجود مفتاح في map في Go: دليل شامل

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

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

ابدأ الدورة

صيد المفاتيح: كيف لا تضيع في غابة Go map

\n

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

\n

إذا كنت قادماً من Python أو JavaScript، فأنت معتاد على أن الوصول إلى مفتاح غير موجود قد يلقي استثناءً أو يعيد undefined. في Go الأمر مختلف. لا توجد استثناءات هنا، ولكن هناك آلية أنيقة خاصة بها. وإذا حاولت قراءة قيمة بمفتاح غير موجود، فلن يتعطل Go، بل سيعيد ببساطة القيمة الصفرية لنوع القيمة.

\n

يبدو هذا مريحاً؟ نعم، لكنه أيضاً فخ. كيف تميز بين حالة "المفتاح غير موجود" وحالة "المفتاح موجود لكن قيمته صفرية"؟ لهذا بالضبط يوجد أسلوب اصطلاحي خاص — comma ok idiom. دعنا نفهمه مرة واحدة وإلى الأبد.

\n\n

كيف تعمل map في Go: نبذة مختصرة

\n

قبل الغوص في عمليات التحقق، دعنا نتذكر ما هي map في Go. هي جدول تجزئة يخزن أزواج مفتاح-قيمة. صيغة التصريح:

\n
// التصريح عن map: المفاتيح نصوص، والقيم أعداد صحيحة\nvar scores map[string]int\n\n// تهيئة map فارغة (إلزامي!)\nscores = make(map[string]int)\n\n// أو مباشرة مع بيانات\nscores := map[string]int{\n    "Alice": 95,\n    "Bob":   87,\n}
\n

نقطة مهمة: إذا حاولت كتابة قيمة في map غير مهيأة (nil map)، سيتعطل البرنامج مع panic. لا تفعل هذا أبداً!

\n\n

الطريقة الرئيسية: الإسناد ذو القيمتين (comma ok idiom)

\n

هذه هي الطريقة الأصح والأكثر اصطلاحية للتحقق مما إذا كان المفتاح موجوداً في map في Go.

\n

الصيغة كالتالي:

\n
value, ok := myMap[key]
\n

هنا:

\n
    \n
  • value — القيمة المقابلة للمفتاح (أو القيمة الصفرية إذا كان المفتاح غير موجود)
  • \n
  • ok — متغير منطقي يساوي true إذا كان المفتاح موجوداً، و false إذا لم يكن موجوداً
  • \n
\n

دعنا نلقي نظرة على مثال كامل:

\n
package main\n\nimport "fmt"\n\nfunc main() {\n    // إنشاء map بدرجات الطلاب\n    grades := map[string]int{\n        "ماريا": 88,\n        "بيتر":  92,\n        "آنا":  0, // نعم، آنا لديها 0 درجة\n    }\n\n    // التحقق من المفتاح "بيتر"\n    if grade, ok := grades["بيتر"]; ok {\n        fmt.Printf("درجة بيتر: %d\\n", grade)\n    } else {\n        fmt.Println("بيتر غير موجود في القائمة")\n    }\n\n    // التحقق من المفتاح "إيفان"\n    if grade, ok := grades["إيفان"]; ok {\n        fmt.Printf("درجة إيفان: %d\\n", grade)\n    } else {\n        fmt.Println("إيفان غير موجود في القائمة")\n    }\n\n    // حالة معقدة: المفتاح "آنا" موجود لكن القيمة 0\n    if grade, ok := grades["آنا"]; ok {\n        fmt.Printf("درجة آنا: %d\\n", grade) // سيطبع: درجة آنا: 0\n    }\n}
\n

لاحظ: بالنسبة لمفتاح "آنا"، سيكون ok مساوياً true، على الرغم من أن القيمة صفرية. لهذا السبب لا يمكن الاعتماد فقط على التحقق من القيمة!

\n\n

لماذا لا يمكن ببساطة المقارنة مع القيمة الصفرية؟

\n

يرتكب العديد من المبتدئين هذا الخطأ. يكتبون شيئاً مثل:

\n
if grades["إيفان"] != 0 {\n    fmt.Println("إيفان موجود في القائمة!")\n}
\n

هذا غير صحيح لسببين:

\n
    \n
  • للأنواع الرقمية: إذا كان إيفان لديه بالفعل درجة 0، فستتجاهله.
  • \n
  • للأنواع الأخرى: القيمة الصفرية قد تكون نصاً فارغاً ("")، أو false، أو nil. لن تتمكن من التمييز بين "لا يوجد مفتاح" و"المفتاح موجود لكن القيمة فارغة".
  • \n
\n

الطريقة الوحيدة الموثوقة هي استخدام comma ok idiom.

\n\n

التحقق من وجود المفتاح دون الحصول على القيمة

\n

أحياناً تحتاج فقط إلى معرفة ما إذا كان المفتاح موجوداً، دون الحاجة إلى القيمة نفسها

المدونات

توصيات الكتب