Rust में स्लाइस को ऐरे के रूप में: यह कठिन क्यों है और इसे सही तरीके से कैसे करें
\n\nजिसने भी Rust में कुछ दिनों से अधिक कोड लिखा है, उसने एक निराशाजनक स्थिति का सामना किया है: आपके पास &[u8] (स्लाइस) है, लेकिन फ़ंक्शन को [u8; 4] (ऐरे) चाहिए। C में, आप बस एक पॉइंटर ले लेते। Python में, आप स्लाइस कर लेते। Rust में... एक मुश्किल नृत्य शुरू होता है। लेकिन घबराएं नहीं - इस जटिलता के पीछे शानदार सुरक्षा है।
इस लेख में, हम Rust में स्लाइस को ऐरे के रूप में कैसे प्राप्त करें सभी संभावित तरीकों से समझेंगे: 'जल्दी और गंदा' से लेकर 'सही और विश्वसनीय' तक। आप जानेंगे कि Rust स्लाइस को ऐरे में बदलने की अनुमति क्यों नहीं देता, और अधिकतम प्रदर्शन के साथ इस 'समस्या' को कैसे हल करें।
\n\nRust स्लाइस को ऐरे में कॉपी करने की अनुमति क्यों नहीं देता?
\n\nकल्पना करें: आप एक पिज़्ज़ा ऑर्डर करते हैं, और वे आपको एक टुकड़ा देते हैं। आप कहते हैं: 'यह पिज़्ज़ा का हिस्सा है, इसे पूरा बनाओ।' स्लाइस के साथ भी ऐसा ही है - यह डेटा के एक हिस्से का संदर्भ है, जबकि ऐरे एक निश्चित लंबाई का स्वामित्व प्रकार है। ऐरे का आकार कंपाइल समय पर ज्ञात होता है, जबकि स्लाइस का आकार केवल रनटाइम पर पता चलता है।
\n\nइसलिए बस let arr: [u8; 4] = slice लिखना संभव नहीं है। कंपाइलर कहेगा: 'माफ करें, मुझे नहीं पता कि आपका स्लाइस 4 तत्वों वाले ऐरे में फिट होगा या नहीं।' Rust सुरक्षा को सबसे ऊपर रखता है - यदि स्लाइस छोटा है, तो आपको कचरा या पैनिक मिलेगा।
विधि 1: try_into() — आधुनिक और सुरक्षित तरीका
\n\nRust 1.47 से शुरू करके, TryInto ट्रेट के माध्यम से एक सुरुचिपूर्ण तरीका आया। यह स्लाइस को ऐरे में बदलने का अनुशंसित तरीका है। यह Result लौटाता है, इसलिए आपको हमेशा पता चलता है कि रूपांतरण सफल हुआ या नहीं।
use std::convert::TryInto;\n\nfn main() {\n let slice: &[u8] = &[10, 20, 30, 40, 50];\n \n // 3 तत्वों का ऐरे प्राप्त करने का प्रयास करें\n let result: Result<[u8; 3], _> = slice[..3].try_into();\n \n match result {\n Ok(arr) => println!("ऐरे: {:?}", arr),\n Err(_) => println!("पर्याप्त तत्व नहीं!"),\n }\n \n // या यदि आप सुनिश्चित हैं तो बस unwrap का उपयोग करें\n let arr: [u8; 4] = slice[..4].try_into().unwrap();\n println!("4 का ऐरे: {:?}", arr);\n}\n\nयह कैसे काम करता है? try_into() विधि रनटाइम पर स्लाइस की लंबाई की जाँच करती है। यदि लंबाई मेल खाती है - तो रूपांतरण करता है, यदि नहीं - तो त्रुटि लौटाता है। यह 99% मामलों के लिए आदर्श समाधान है।
विधि 2: copy_from_slice() — उन लोगों के लिए जो नियंत्रण पसंद करते हैं
\n\nयदि आपके पास पहले से एक ऐरे है (उदाहरण के लिए, शून्य से प्रारंभ किया गया), तो आप स्लाइस से डेटा कॉपी कर सकते हैं। इस विधि के लिए आवश्यक है कि स्लाइस ऐरे से छोटा न हो - अन्यथा पैनिक होगा।
\n\nfn main() {\n let slice: &[u32] = &[100, 200, 300];\n let mut arr: [u32; 3] = [0; 3]; // एक खाली ऐरे बनाएँ\n \n arr.copy_from_slice(slice);\n println!("कॉपी किया गया: {:?}", arr);\n \n // यदि स्लाइस लंबा है - तो एक उपसमूह लें\n let long_slice = &[1, 2, 3, 4, 5];\n let mut small_arr = [0u8; 2];\n small_arr.copy_from_slice(&long_slice[..2]);\n println!("स्लाइस का भाग: {:?}", small_arr);\n}\n\nमहत्वपूर्ण: copy_from_slice केवल उन प्रकारों के लिए काम करता है जो Copy को लागू करते हैं (जैसे, संख्याएँ)। स्ट्रिंग के लिए clone_from_slice का उपयोग करें।
विधि 3: मैन्युअल इटरेशन — चरम खिलाड़ियों के लिए
\n\nकभी-कभी कुछ गैर-मानक करने की आवश्यकता होती है। उदाहरण के लिए, क्रम बदलने या फ़िल्टर करने के साथ स्लाइस को बदलना। तब आप मैन्युअल रूप से जा सकते हैं:
\n\nfn slice_to_array<T: Copy, const N: usize>(slice: &[T]) -> Option<[T; N]> {\n if slice.len() != N {\n return None;\n }\n \n let mut arr = [unsafe { std::mem::zeroed() }; N];\n for (i, &val) in slice.iter().enumerate() {\n arr[i] = val;\n }\n Some(arr)\n}\n\nfn main() {\n