Go में Code review: क्या जाँचें ताकि कोड फटे नहीं
\n\nCode review — यह सिर्फ Jira में टिक लगाने या पुल-रिक्वेस्ट पर सहकर्मी से बहस करने का बहाना नहीं है। यह शायद प्रोडक्शन में खुद को नुकसान न पहुँचाने का सबसे ईमानदार तरीका है। और जब बात Go की आती है — एक ऐसी भाषा जिसे सादगी के लिए पसंद किया जाता है और "यहाँ जेनेरिक कहाँ हैं?" (स्पॉयलर: वे अब मौजूद हैं) के लिए नफरत की जाती है — तो रिव्यू एक कला बन जाता है। इस लेख में हम देखेंगे कि Go में code review के दौरान वास्तव में क्या देखना चाहिए, ताकि आपका कोड न केवल काम करे बल्कि देखने में भी अच्छा लगे। चलिए शुरू करते हैं!
\n\n1. त्रुटि प्रबंधन: न नज़रअंदाज़ करें, न डरें
\n\nGo में अपवाद (exceptions) नहीं हैं। यहाँ सब कुछ ईमानदार है: यदि कोई फ़ंक्शन विफल हो सकता है, तो वह error लौटाता है। शुरुआती लोगों की सबसे आम समस्या अंडरस्कोर के माध्यम से त्रुटियों को नज़रअंदाज़ करना है। याद रखें: "Never ignore an error" — यह सिर्फ एक मंत्र नहीं है, यह एक नियम है।
कोड में क्या जाँचें:
\n- \n
- err != nil की जाँच — यह हर जगह होनी चाहिए जहाँ फ़ंक्शन त्रुटि लौटाता है। भले ही आपको यकीन हो कि "यहाँ कोई त्रुटि नहीं होगी"। \n
- लॉगिंग या आगे भेजना — त्रुटि को या तो संदर्भ के साथ लॉग किया जाना चाहिए, या ऊपर लौटाया जाना चाहिए। इसे दबाना बुरा व्यवहार है। \n
- Sentinel-त्रुटियों से तुलना — सीधी
==तुलना के बजायerrors.Is()औरerrors.As()का उपयोग करें। \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\n2. गोरूटीन और समवर्तीता: अराजकता में व्यवस्था
\n\nगोरूटीन Go की सुपरपावर हैं। लेकिन बड़ी शक्ति के साथ बड़ी जिम्मेदारी आती है। रिव्यू में हम अक्सर गोरूटीन लीक, डेटा रेस और लॉक देखते हैं। समवर्तीता की जाँच के बिना Go में code review बिना सीट बेल्ट के स्पोर्ट्स कार चलाने जैसा है।
\n\nगोरूटीन के लिए चेक-लिस्ट:
\n- \n
- गोरूटीन शुरू करना — हमेशा जीवनकाल को नियंत्रित करें।
sync.WaitGroupया कॉन्टेक्स्ट का उपयोग करें। \n - डेटा रेस — जाँचें कि साझा डेटा तक पहुँच म्यूटेक्स या चैनल द्वारा सुरक्षित है।
go test -raceचलाएँ। \n - गोरूटीन में पैनिक — यदि गोरूटीन पैनिक करता है, तो पूरा प्रोग्राम क्रैश हो जाएगा। प्रोडक्शन कोड में हमेशा
recoverका उपयोग करें। \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\n3. इंटरफ़ेस: छोटे और सार्थक
\n\nGo में इंटरफ़ेस अनुबंध हैं। लेकिन Java के विपरीत, उन्हें बड़ा होना ज़रूरी नहीं है। Go समुदाय में एक सिद्धांत है: "इंटरफ़ेस जितना छोटा, उतना बेहतर"। एक विधि — आदर्श। दो — ठीक। तीन — पहले से ही संदिग्ध।
\n\nक्या देखें:
\n- \n
- इंटरफ़ेस का आकार — यदि इसमें 3-4 से अधिक विधियाँ हैं, तो इसे विभाजित करने पर विचार करें। \n
- इंटरफ़ेस स्वीकार करें, स्ट्रक्चर लौटाएँ — Go की क्लासिक बुद्धि। यह कोड को लचीला और परीक्षण योग्य बनाता है। \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
ब्लॉग
पुस्तक अनुशंसाएँ
यह भी पढ़ें