Rust में चरण 3, 5 या 100 के साथ संख्याओं पर कैसे चलें? पूर्ण विश्लेषण
\n\nकल्पना करें: आप Rust में कोड लिख रहे हैं और आपको 0 से 20 तक सभी सम संख्याएँ प्रदर्शित करनी हैं। या, मान लीजिए, अनुक्रम 0, 5, 10, 15, 20 बनाना है। Python में आप बस range(0, 21, 5) लिखते — और हो जाता है। Rust में क्या करें? यहाँ कुछ बारीकियाँ हैं, और आज हम उन पर चर्चा करेंगे।
यह प्रश्न Stack Overflow पर सबसे लोकप्रिय में से एक है (हज़ारों बार देखा गया)। और कोई आश्चर्य नहीं: मानक for i in 0..10 केवल चरण 1 के साथ काम करता है। लेकिन अगर दूसरे चरण की आवश्यकता हो? पता चला है, तीन पूरे तरीके हैं, और प्रत्येक के अपने फायदे और नुकसान हैं।
हम केवल कोड नहीं दिखाएंगे — हम प्रदर्शन, पठनीयता और लचीलेपन के आधार पर दृष्टिकोणों की तुलना करेंगे। चलिए शुरू करते हैं!
\n\nRust में चरण के साथ बिल्ट-इन range क्यों नहीं है?
\n\nसंक्षिप्त उत्तर: क्योंकि Rust में Range एक सरल इटरेटर है जो पूर्णांकों का अनुक्रम उत्पन्न करता है। यह डिफ़ॉल्ट रूप से चरण का समर्थन नहीं करता ताकि यह यथासंभव हल्का और पूर्वानुमानित रहे। लेकिन डेवलपर्स ने ऐसे तरीके प्रदान किए हैं जो इस समस्या को हल करते हैं।
लंबा उत्तर: Rust पारिस्थितिकी तंत्र में दर्शन "स्पष्ट, अंतर्निहित से बेहतर है" है। रेंज सिंटैक्स में चरण डालने के बजाय, निर्माताओं ने इटरेटर को अनुकूलित करने के लिए लचीले उपकरण सुझाए। और यह जितना लगता है उससे अधिक संभावनाएँ खोलता है।
\n\nतरीका 1: step_by() — सबसे सीधा रास्ता
\n\nRust की मानक लाइब्रेरी में step_by(n) विधि है, जो एक इटरेटर बनाती है जो हर n-1 तत्वों को छोड़ता है। यह इस प्रकार काम करता है:
fn main() {\n // 0 से 20 तक चरण 5 के साथ संख्याएँ प्रदर्शित करें\n for i in (0..=20).step_by(5) {\n println!("{}", i);\n }\n // आउटपुट: 0, 5, 10, 15, 20\n}\n\nध्यान दें: मैंने 0..=20 (समावेशी) का उपयोग किया, न कि 0..20 (अनन्य) का। यदि 10 तक चरण 3 चाहिए, तो (0..10).step_by(3) लिखें — हमें 0, 3, 6, 9 मिलेगा।
step_by() के लाभ:
\n- \n
- सरलता — एक पंक्ति, कोई क्लोज़र नहीं \n
- पठनीयता — तुरंत स्पष्ट होता है कि क्या कर रहे हैं \n
- प्रदर्शन — न्यूनतम ओवरहेड \n
नुकसान:
\n- \n
- केवल पूर्णांकों (i32, u64, आदि) के साथ काम करता है \n
- प्रत्येक पुनरावृत्ति पर गतिशील चरण सेट नहीं किया जा सकता \n
- केवल Rust 1.28 में दिखाई दिया (लेकिन यह पहले से ही काफी पुराना है) \n
यह विधि 90% कार्यों के लिए आदर्श विकल्प है। यदि आपको बस स्थिर चरण के साथ संख्याओं पर चलना है — step_by() का उपयोग करें।
तरीका 2: filter() — जब चरण एक शर्त है
\n\nलेकिन क्या होगा यदि चरण स्थिर नहीं है? उदाहरण के लिए, उन संख्याओं को प्रदर्शित करना जो 3 से पूरी तरह विभाज्य हैं। या वे संख्याएँ जिनके अंकों का योग 5 से अधिक है। यहाँ filter() मदद करता है:
fn main() {\n // 0 से 30 तक सभी संख्याएँ, 4 के गुणज\n for i in (0..=30).filter(|x| x % 4 == 0) {\n println!("{}", i);\n }\n // आउटपुट: 0, 4, 8, 12, 16, 20, 24, 28\n\n // और अब — वे संख्याएँ जो 3 से विभाज्य नहीं हैं\n for i in (0..20).filter(|x| x % 3 != 0) {\n println!("{}", i);\n }\n // आउटपुट: 1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19\n}\n\nयहाँ हम एक क्लोज़र पास करते हैं जो प्रत्येक संख्या की जाँच करता है। filter() केवल उन तत्वों को रखता है जिनके लिए शर्त सत्य है।
filter() step_by() से कब बेहतर है:
\n- \n
- चरण मान पर निर्भर करता है (जैसे, "सभी अभाज्य संख्याएँ") \n
- अन्य शर्तों के साथ संयोजन करने की आवश्यकता है \n
- चरण स्थिर नहीं है (जैसे, फाइबोनैचि संख्याएँ) \n
नुकसान:
\n- \n
- step_by() से थोड़ा धीमा — प्रत्येक संख्या की जाँच करनी पड़ती है \n
- शुरुआती लोगों के लिए कोड कम स्पष्ट हो सकता है \n
व्यक्तिगत रूप से, मैं filter() का उपयोग करता हूँ जब मुझे केवल "हर n-वाँ" नहीं, बल्कि "हर कोई जो नियम से मेल खाता है" चाहिए। यह अधिक शक्तिशाली है, लेकिन अधिक ध्यान देने की आवश्यकता है।