مراجعة الكود بلغة Go: ما الذي يجب التحقق منه لتجنب انفجار الكود

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

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

ابدأ الدورة

مراجعة الكود بلغة Go: ما الذي يجب التحقق منه لتجنب انفجار الكود

\n\n

مراجعة الكود ليست مجرد علامة اختيار في Jira أو سبب للشجار مع زميل في تعليقات طلب السحب. إنها، ربما، الطريقة الأكثر صدقًا لتجنب إطلاق النار على قدمك في الإنتاج. وعندما يتعلق الأمر بلغة Go - اللغة التي يعشقها الجميع لبساطتها ويكرهونها بسبب "أين هي الأدوية العامة هنا؟" (المفسد: لقد أصبحت موجودة بالفعل) - تصبح المراجعة فنًا. في هذه المقالة، سنناقش بالضبط ما الذي يجب النظر إليه أثناء مراجعة الكود بلغة Go، حتى لا يعمل الكود الخاص بك فحسب، بل يبهج العين أيضًا. هيا بنا!

\n\n

1. معالجة الأخطاء: لا تتجاهل، لا تخف

\n\n

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

\n\n

ما الذي يجب التحقق منه في الكود:

\n
    \n
  • التحقق من err != nil - يجب أن يكون موجودًا في كل مكان تُرجع فيه الدالة خطأ. حتى لو كنت متأكدًا من أنه "لن يكون هناك خطأ هنا".
  • \n
  • التسجيل أو الإعادة - يجب إما تسجيل الخطأ مع السياق، أو إعادته إلى الأعلى. إخفاؤه هو أمر غير لائق.
  • \n
  • المقارنة مع أخطاء الحارس - استخدم errors.Is() و errors.As()، وليس المقارنة المباشرة ==.
  • \n
\n\n
// سيء: تجاهل الخطأ\nfile, _ := os.Open("config.yaml")\n\n// جيد: التحقق والتسجيل\nfile, err := os.Open("config.yaml")\nif err != nil {\n    log.Printf("فشل فتح ملف الإعدادات: %v", err)\n    return err\n}\ndefer file.Close()\n
\n\n

2. الغوروتينات والتوازي: النظام في الفوضى

\n\n

الغوروتينات هي القوة الخارقة لـ Go. لكن القوة العظيمة تأتي بمسؤولية عظيمة. في المراجعة، نرى غالبًا تسربات الغوروتينات، وسباقات البيانات، والعمليات المحظورة. مراجعة الكود في Go دون التحقق من التوازي هي مثل قيادة سيارة رياضية بدون حزام أمان.

\n\n

قائمة مراجعة للغوروتينات:

\n
    \n
  • تشغيل الغوروتينات - تحكم دائمًا في دورة حياتها. استخدم sync.WaitGroup أو السياقات.
  • \n
  • سباقات البيانات - تحقق من أن الوصول إلى البيانات المشتركة محمي بواسطة mutex أو قناة. قم بتشغيل go test -race.
  • \n
  • الذعر في الغوروتين - إذا أصيب الغوروتين بالذعر، سينهار البرنامج بأكمله. في كود الإنتاج، استخدم دائمًا recover.
  • \n
\n\n
// سيء: غوروتين بدون تحكم\ngo func() {\n    // قد يسقط ويقتل العملية بأكملها\n    doWork()\n}()\n\n// جيد: مع WaitGroup و recover\nvar wg sync.WaitGroup\nwg.Add(1)\ngo func() {\n    defer wg.Done()\n    defer func() {\n        if r := recover(); r != nil {\n            log.Printf("الغوروتين سقط: %v", r)\n        }\n    }()\n    doWork()\n}()\nwg.Wait()\n
\n\n

3. الواجهات: صغيرة وفي محلها

\n\n

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

\n\n

ما الذي يجب النظر إليه:

\n
    \n
  • حجم الواجهة - إذا كان بها أكثر من 3-4 طرق، فكر في تقسيمها.
  • \n
  • استقبل الواجهات، وأعد الهياكل - حكمة Go الكلاسيكية. تجعل الكود مرنًا وقابلاً للاختبار.
  • \n
  • لا تحدد الواجهات مسبقًا - دع المستهلك هو من ينشئها، وليس المنتج.
  • \n
\n\n
// سيء: واجهة ضخمة\ntype Storage interface {\n    Save(data []byte) error\n    Load(id string) ([]byte, error)\n    Delete(id string) error\n    List() ([]string, error)\n    Connect() error\n    Close() error\n}\n\n// جيد: واجهات صغيرة\ntype Saver interface {\n    Save(data []byte) error\n}\ntype Loader interface {\n    Load(id string) ([]byte, error)\n}\n

المدونات

توصيات الكتب