أخطاء المبتدئين في Go: 5 أخطاء تحول الكود إلى جحيم

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

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

ابدأ الدورة

لماذا تبدو Go بسيطة ولكنها تحطم المبتدئين؟

\n\n

Go (أو Golang) هي لغة تم إنشاؤها بهدف واحد: أن يعاني المبرمجون أقل. بناء جملة بسيط، توازي مدمج، ترجمة سريعة - يبدو أنه يمكن تعلمها في أسبوع. ونعم، يمكن تعلمها. لكن "كتابة كود جيد" و"كتابة كود بلغة Go" قصتان مختلفتان.

\n\n

غالبًا ما يجلب المبتدئون عادات من Python أو JavaScript أو Java ويحاولون تطبيقها على Go. النتيجة - أخطاء يصعب اكتشافها، ذعر في وقت التشغيل، وشعور بأن "Go معطلة". تنبيه: Go ليست معطلة. إنها فقط تفكر بشكل مختلف.

\n\n

في هذه المقالة، سنحلل 5 من أكثر الأخطاء شيوعًا عند تعلم Go. إذا كنت مبتدئًا - اقرأ بعناية. إذا كنت تكتب بالفعل بلغة Go - تحقق مما إذا كنت لا تزال ترتكبها.

\n\n

الخطأ رقم 1: تجاهل الأخطاء (وعادة من Python)

\n\n

في Python أو JavaScript، اعتدت على أن الدالة يمكنها إرجاع نتيجة أو إلقاء استثناء. تقوم بتغليف الاستدعاء في try/catch وتعيش بسلام. في Go، الأمر مختلف تمامًا: لا توجد استثناءات. هناك فقط قيم مرتجعة، واحدة منها هي الخطأ.

\n\n

الخطأ الأكثر شيوعًا للمبتدئين هو كتابة result, _ := someFunc() ونسيان الخطأ. أو الأسوأ من ذلك، عدم التحقق منه ببساطة:

\n\n
// سيء: تم تجاهل الخطأ\nfile, _ := os.Open("config.yaml")\n// إذا لم يكن الملف موجودًا - file == nil، والسطر التالي سينهار مع ذعر\ndefer file.Close()\n
\n\n

في Go، الخطأ ليس شيئًا مخيفًا. إنه مجرد قيمة. يجب التحقق منه. دائمًا. بدون استثناءات.

\n\n

كيف تفعل ذلك بشكل صحيح؟

\n\n
// جيد: نتحقق من الخطأ فورًا\nfile, err := os.Open("config.yaml")\nif err != nil {\n    log.Fatalf("فشل فتح الملف: %v", err)\n}\ndefer file.Close()\n
\n\n

هذا ليس جنون ارتياب. إنه انضباط. تعلمك Go أن تكون دقيقًا. إذا تجاهلت خطأ في الإنتاج - استعد لسقوط الخدمة في الساعة 3 صباحًا، مع صمت تام في السجلات.

\n\n

نصيحة: لا تستخدم أبدًا _ للخطأ، إلا إذا كنت متأكدًا بنسبة 100% أنه لن يحدث أبدًا. ومثل هذه المواقف تكاد لا توجد في الكود الحقيقي.

\n\n

الخطأ رقم 2: الذعر حيثما يكون الخطأ مطلوبًا

\n\n

في Go، هناك آلية panic و recover. غالبًا ما يخلط المبتدئون بينها وبين الاستثناءات ويبدأون في إلقاء الذعر عند أي مشكلة. هذا خطأ.

\n\n

panic هو توقف طارئ للبرنامج. إنه مخصص للحالات التي يكون فيها استمرار العمل مستحيلًا: على سبيل المثال، إلغاء الإشارة إلى مؤشر فارغ أو تجاوز حدود المصفوفة. استخدام panic لمعالجة منطق الأعمال أمر غير لائق.

\n\n
// سيء: ذعر بدلاً من خطأ\nfunc divide(a, b int) int {\n    if b == 0 {\n        panic("القسمة على صفر!")\n    }\n    return a / b\n}\n
\n\n

النهج الصحيح هو إرجاع خطأ:

\n\n
// جيد: نعيد خطأ\nfunc divide(a, b int) (int, error) {\n    if b == 0 {\n        return 0, fmt.Errorf("القسمة على صفر")\n    }\n    return a / b, nil\n}\n
\n\n

استخدم panic فقط للحالات الحرجة حقًا. كل شيء آخر هو أخطاء. Go تمنحك error ليس من أجل لا شيء.

\n\n

الخطأ رقم 3: العمل غير الصحيح مع goroutines وغياب التزامن

\n\n

Goroutines هي ربما أفضل ميزة في Go. لكنها أيضًا الأكثر خطورة للمبتدئين. الصورة النمطية: تشغيل 1000 goroutine، الكتابة إلى متغير مشترك - وتحصل على سباق بيانات (data race).

\n\n
// سيء: سباق بيانات\nvar counter int\nfor i := 0; i < 1000; i++ {\n    go func() {\n        counter++ // غير آمن!\n    }()\n}\ntime.Sleep(time.Second)\nfmt.Println(counter) // النتيجة غير متوقعة\n
\n\n

لماذا هذه مشكلة؟ لأن counter++ ليست عملية ذرية. إنها تتكون من قراءة وزيادة وكتابة. يمكن لـ goroutine قراءة نفس القيمة، وزيادتها

المدونات

توصيات الكتب