Rust में डिफ़ॉल्ट आर्गुमेंट्स क्यों नहीं हैं — और इसका हल क्या है
\n\nअगर आप Python, JavaScript या C++ से Rust में आए हैं, तो आपको एक बात हैरान कर सकती है: Rust में डिफ़ॉल्ट आर्गुमेंट्स के लिए कोई बिल्ट-इन सपोर्ट नहीं है। आप सीधे fn greet(name = "दुनिया") नहीं लिख सकते — कंपाइलर मना कर देगा।
लेकिन परेशान न हों! Rust इसके लिए कुछ ज़्यादा लचीले और सुरक्षित तरीके देता है। इस ट्यूटोरियल में हम 3 सिद्ध तरीकों से डिफ़ॉल्ट आर्गुमेंट्स जैसा व्यवहार लागू करेंगे। आप सीखेंगे कि Option<T>, कॉन्फ़िगरेशन स्ट्रक्चर और Builder पैटर्न का उपयोग कैसे करें — और अपनी ज़रूरत के लिए सबसे अच्छा तरीका कैसे चुनें।
यह लेख Stack Overflow के एक रियल क्वेश्चन (50,000+ व्यूज़) पर आधारित है — जिसे हमने एजुकेशनल फ़ॉर्मेट में ढाला है। चलिए शुरू करते हैं!
\n\nतरीका 1. Option<T> का उपयोग — सबसे आसान विकल्प
\n\nसबसे सीधा तरीका है आर्गुमेंट्स को Option<T> के रूप में लेना और फ़ंक्शन के अंदर डिफ़ॉल्ट वैल्यू सेट करना।
fn greet(name: Option<&str>) {\n let name = name.unwrap_or("दुनिया");\n println!("नमस्ते, {}!", name);\n}\n\nfn main() {\n greet(Some("अन्ना")); // नमस्ते, अन्ना!\n greet(None); // नमस्ते, दुनिया!\n}\n\n\nफ़ायदे:
\n- \n
- बहुत कम कोड \n
- शुरुआती लोगों के लिए भी आसान \n
- अतिरिक्त स्ट्रक्चर की ज़रूरत नहीं \n
नुकसान:
\n- \n
- हर कॉल में
Some(...)याNoneलपेटना पड़ता है \n - अगर कई पैरामीटर हों तो कोड बोझिल हो जाता है \n
यह तरीका 1-2 ऑप्शनल पैरामीटर वाले फ़ंक्शन के लिए बढ़िया है। लेकिन अगर पैरामीटर ज़्यादा हों, तो पढ़ने में मुश्किल होती है।
\n\nतरीका 2. कॉन्फ़िगरेशन स्ट्रक्चर — साफ़ और स्केलेबल
\n\nजब पैरामीटर 3, 5 या 10 हो जाएँ, तब कॉन्फ़िगरेशन स्ट्रक्चर काम आता है। आप एक अलग टाइप बनाते हैं जो सभी सेटिंग्स स्टोर करता है, और उसके लिए Default ट्रेट इम्प्लीमेंट करते हैं।
struct GreetConfig {\n name: String,\n greeting: String,\n excitement_level: u8,\n}\n\nimpl Default for GreetConfig {\n fn default() -> Self {\n Self {\n name: "दुनिया".to_string(),\n greeting: "नमस्ते".to_string(),\n excitement_level: 1,\n }\n }\n}\n\nfn greet(config: GreetConfig) {\n let excitement = "!".repeat(config.excitement_level as usize);\n println!("{}, {}{}", config.greeting, config.name, excitement);\n}\n\nfn main() {\n // डिफ़ॉल्ट वैल्यू का उपयोग\n greet(GreetConfig::default());\n // आउटपुट: नमस्ते, दुनिया!\n\n // सिर्फ़ ज़रूरी चीज़ें बदलें\n greet(GreetConfig {\n name: "अन्ना".to_string(),\n ..Default::default()\n });\n // आउटपुट: नमस्ते, अन्ना!\n\n // पूरी तरह कस्टम कॉल\n greet(GreetConfig {\n name: "संसार".to_string(),\n greeting: "प्रणाम".to_string(),\n excitement_level: 3,\n });\n // आउटपुट: प्रणाम, संसार!!!\n}\n\n\nफ़ायदे:
\n- \n
- अधिकतम लचीलापन \n
- फ़ंक्शन सिग्नेचर बदले बिना नए फ़ील्ड जोड़ सकते हैं \n
..Default::default()सिंटैक्स बहुत पढ़ने लायक है \n
नुकसान:
\n- \n
- ज़्यादा boilerplate कोड चाहिए \n
Defaultट्रेट को स्पष्ट रूप से इम्प्लीमेंट करना पड़ता है \n
यह रियल प्रोजेक्ट्स के लिए आदर्श है: लाइब्रेरी, कॉन्फ़िगरेशन फ़ंक्शन, जटिल API।
\n\nतरीका 3. Builder Pattern — चेनिंग पसंद करने वालों के लिए
\n\nBuilder पैटर्न Rust इकोसिस्टम का क्लासिक है। आप एक बिल्डर स्ट्रक्चर बनाते हैं जो पैरामीटर जमा करता है, और अंत में build() मेथड कॉल करता है।
struct Greeter {\n name: String,\n greeting: String,\n excitement_level: u8,\n}\n\nstruct GreeterBuilder {\n nam