परिचय: "ग्लोबल वेरिएबल्स कहाँ हैं?" — Rust में शुरुआती का पहला झटका
\n\nआपने अभी-अभी Rust सीखना शुरू किया है, कुछ प्रोग्राम लिखे हैं, और अचानक आपको एहसास होता है: आपको एक ऐसे वेरिएबल की आवश्यकता है जो कोड में कहीं से भी एक्सेस किया जा सके। Python या JavaScript में, आप बस शीर्ष स्तर पर global_var = 42 लिख देते — और हो जाता है। लेकिन Rust में... कंपाइलर आपको तिरस्कार भरी नज़र से देखता है और एक एरर देता है।
प्रश्न "Is it possible to use global variables in Rust?" Stack Overflow पर सबसे लोकप्रिय प्रश्नों में से एक है। और यह सही भी है। Rust, कई अन्य भाषाओं के विपरीत, आपको बस एक ग्लोबल वेरिएबल घोषित करने की अनुमति नहीं देता है। क्यों? क्योंकि मेमोरी सुरक्षा सिर्फ एक फैशनेबल शब्द नहीं है, बल्कि भाषा की नींव है।
\n\nइस लेख में, हम Rust में ग्लोबल डेटा के साथ काम करने के सभी तरीकों का विश्लेषण करेंगे: सरल कॉन्स्टेंट से लेकर थ्रेड-सेफ स्टोरेज तक। आप सीखेंगे कि सुरक्षा से समझौता किए बिना कंपाइलर की सीमाओं को कैसे पार किया जाए, और ग्लोबल वेरिएबल्स कब बुराई हैं और कब आवश्यकता।
\n\nRust "सामान्य" ग्लोबल वेरिएबल्स को क्यों प्रतिबंधित करता है?
\n\nसमाधान खोजने से पहले, आइए समस्या को समझें। Rust में स्वामित्व (ownership) और उधार (borrowing) के सख्त नियम हैं। एक ग्लोबल वेरिएबल जिसे किसी भी थ्रेड से किसी भी समय बदला जा सकता है — यह डेटा रेस (data race) का सीधा रास्ता है।
\n\nकल्पना करें: दो थ्रेड एक साथ एक ही ग्लोबल वेरिएबल में अलग-अलग मान लिखने का प्रयास कर रहे हैं। परिणाम अप्रत्याशित है। C++ या C में, यह अनिर्धारित व्यवहार की ओर ले जाता है। Rust गारंटी देता है कि ऐसा कुछ कंपाइल ही नहीं होगा।
\n\nइसलिए कंपाइलर हमसे स्पष्ट रूप से निर्दिष्ट करने की अपेक्षा करता है:
\n- \n
- वेरिएबल अपरिवर्तनीय है?
constयाstaticका उपयोग करें। \n - वेरिएबल परिवर्तनीय है और एक ही थ्रेड में उपयोग किया जाता है?
static mutका उपयोग करें (unsafeके साथ)। \n - वेरिएबल परिवर्तनीय है और कई थ्रेड्स में उपयोग किया जाता है?
Mutex,RwLockया परमाणु प्रकारों का उपयोग करें। \n
विधि 1: कॉन्स्टेंट (const) — सबसे सुरक्षित विकल्प
\n\nयदि आपका "ग्लोबल मान" वास्तव में एक कॉन्स्टेंट है जो कभी नहीं बदलता है, तो const का उपयोग करें:
const MAX_CONNECTIONS: u32 = 100;\nconst DATABASE_URL: &str = "postgresql://localhost:5432/mydb";\n\nfn main() {\n println!("अधिकतम कनेक्शन: {}", MAX_CONNECTIONS);\n}\n\nRust में कॉन्स्टेंट सिर्फ वेरिएबल नहीं हैं। वे कंपाइलर द्वारा उपयोग के स्थान पर इनलाइन किए जाते हैं। यानी, कंपाइलेशन के दौरान MAX_CONNECTIONS को संख्या 100 से बदल दिया जाएगा। यह कुशल है, लेकिन इसका मतलब है कि कॉन्स्टेंट का मेमोरी में कोई निश्चित पता नहीं है। यदि आपको मेमोरी में एक स्थान चाहिए (उदाहरण के लिए, FFI के लिए), तो static का उपयोग करें।
विधि 2: स्टैटिक वेरिएबल्स (static)
\n\nयदि आपको मेमोरी में एक निश्चित पते वाले ग्लोबल वेरिएबल की आवश्यकता है, तो static का उपयोग करें:
static APP_NAME: &str = "My Rust Application";\nstatic VERSION: u32 = 1;\n\nfn main() {\n println!("{} संस्करण {} चल रहा है", APP_NAME, VERSION);\n}\n\nडिफ़ॉल्ट रूप से, static वेरिएबल अपरिवर्तनीय होते हैं। यह मल्टी-थ्रेडेड वातावरण में सुरक्षा सुनिश्चित करता है। लेकिन क्या होगा यदि आपको ग्लोबल स्टेट को बदलने की आवश्यकता है?
विधि 3: परिवर्तनीय स्टैटिक वेरिएबल्स (static mut) — सावधान, unsafe!
\n\nRust आपको static mut के साथ एक परिवर्तनीय स्टैटिक वेरिएबल घोषित करने की अनुमति देता है। लेकिन एक शर्त है: ऐसे वेरिएबल को पढ़ने या लिखने के लिए unsafe ब्लॉक की आवश्यकता होती है।
static mut COUNTER: u32 = 0;\n\nfn increment() {\n unsafe {\n COUNTER += 1;\n }\n}\n\nfn main() {\n increment();\n unsafe {\n println!("काउंटर: {}", COUNTER);\n }\n}\n\nमहत्वपूर्ण: