Rust में HashMap बनाना: 2025 में दर्द से सुंदरता तक
\n\nअगर आपने कभी Rust में कोड लिखा है और सोचा है "मैं HashMap लिटरल कैसे बनाऊं?" — तो आप अकेले नहीं हैं। यह सवाल Stack Overflow पर हज़ारों बार देखा गया है, और सही भी है। Python या JavaScript जैसी भाषाओं में डिक्शनरी बनाना बस कुछ curly braces का मामला है। Rust में यह थोड़ा जटिल है… लेकिन केवल पहली नज़र में।
\n\n2025 में, Rust की इकोसिस्टम बहुत आगे बढ़ चुकी है। नए मैक्रोज़ आए हैं, कॉन्स्टेंट के साथ काम करना बेहतर हुआ है, और कंपाइलर और भी स्मार्ट हो गया है। इस लेख में हम HashMap बनाने के सभी तरीकों पर चर्चा करेंगे, क्लासिक से लेकर सबसे आधुनिक तक। आप सीखेंगे कि कैसे न केवल काम करने वाला, बल्कि सुंदर और कुशल कोड लिखें।
\n\nचलिए शुरू करते हैं! 🦀
\n\nRust में HashMap का बिल्ट-इन लिटरल क्यों नहीं है?
\n\nयह शायद शुरुआती लोगों का सबसे आम सवाल है। इसका जवाब सरल है: Rust Python नहीं है। Rust में कलेक्शन के लिए सिंटैक्स में कोई "जादू" नहीं है, क्योंकि भाषा पूर्वानुमान और मेमोरी पर नियंत्रण पर जोर देती है।
\n\nकल्पना करें कि आप लिखते हैं:
\n\nlet map = {"key1": "value1", "key2": "value2"};\n\nयह तार्किक लगता है? हाँ। लेकिन क्या होगा अगर कीज़ या वैल्यू स्ट्रिंग नहीं हैं, बल्कि कुछ जटिल स्ट्रक्चर हैं? कंपाइलर कैसे जानेगा कि कौन सा एलोकेटर इस्तेमाल करना है? हैशिंग का क्या? Rust ये निर्णय डेवलपर पर छोड़ता है।
\n\nयही कारण है कि स्टैंडर्ड लाइब्रेरी में HashMap बनाने के लिए HashMap::new() और .insert() मेथड का उपयोग किया जाता है। लेकिन, माना कि तीन जोड़ियों का डिक्शनरी बनाने के लिए 10 लाइन कोड लिखना दर्दनाक है। सौभाग्य से, इसके समाधान हैं।
तरीका #1: क्लासिक — HashMap::new() + insert()
\n\nबेसिक से शुरू करते हैं। यह सबसे सरल और पारदर्शी तरीका है। आप एक खाली HashMap बनाते हैं और उसे भरते हैं:
\n\nuse std::collections::HashMap;\n\nfn main() {\n let mut scores = HashMap::new();\n scores.insert("Alice".to_string(), 42);\n scores.insert("Bob".to_string(), 27);\n scores.insert("Charlie".to_string(), 35);\n\n println!("{:?}", scores);\n}\n\nफायदे:
\n- \n
- प्रक्रिया पर पूर्ण नियंत्रण। \n
- शर्त के अनुसार एलिमेंट जोड़ सकते हैं। \n
- किसी अतिरिक्त डिपेंडेंसी की आवश्यकता नहीं। \n
नुकसान:
\n- \n
- बहुत अधिक कोड। \n
mutकी आवश्यकता है। \n - कॉन्स्टेंट के लिए उपयुक्त नहीं। \n
यह तरीका डायनामिक डेटा भरने के लिए अच्छा है, लेकिन स्टैटिक डेटा के लिए यह अनावश्यक है।
\n\nतरीका #2: from() — जब डेटा पहले से तैयार हो
\n\nअगर आपके पास टपल का वेक्टर है, तो आप HashMap::from() का उपयोग कर सकते हैं:
use std::collections::HashMap;\n\nfn main() {\n let data = vec![\n ("Alice", 42),\n ("Bob", 27),\n ("Charlie", 35),\n ];\n\n let scores: HashMap<&str, i32> = HashMap::from(data);\n println!("{:?}", scores);\n}\n\nयह "लिटरल" के करीब है। यह साफ दिखता है, लेकिन फिर भी एक इंटरमीडिएट वेक्टर की आवश्यकता है। यह तेज़ काम करता है, लेकिन बड़े डेटा सेट के लिए डबल मेमोरी आवंटन के कारण अकुशल हो सकता है।
\n\nतरीका #3: collect() — फंक्शनल दृष्टिकोण
\n\nइटरेटर के प्रशंसकों को यह तरीका पसंद आएगा:
\n\nuse std::collections::HashMap;\n\nfn main() {\n let scores: HashMap<&str, i32> = [\n ("Alice", 42),\n ("Bob", 27),\n ("Charlie", 35),\n ].iter().cloned().collect();\n\n println!("{:?}", scores);\n}\n\nसुंदर? हाँ। पढ़ने में आसान? कुछ हद तक। लेकिन यह Rust में सबसे इडियोमैटिक तरीकों में से एक है। .iter().cloned().collect() एक स्टैंडर्ड पैटर्न है एरे को कलेक्शन में बदलने के लिए।
वैसे, अगर आपकी कीज़ और वैल्यू Copy को इम्प्लीमेंट करती हैं, तो आप .cloned() के बजाय .copied() का उपयोग कर सकते हैं — यह थोड़ा तेज़ है।
तरीका #4: hashmap! मैक्रो — 2025 से मुक्ति
\n\nअब हम आते हैं