«मैं String, &str, Vec<u8> और &[u8] के बीच कैसे रूपांतरित करूं?» — Rust में अनुकूलन के लिए आपकी चेकलिस्ट
\n\nयदि आपने कभी Rust में टेक्स्ट या बाइट्स के साथ काम करने वाला कोड लिखा है, तो आपने निश्चित रूप से इस प्रश्न का सामना किया होगा: «मैं String को &str में कैसे बदलूं? और Vec<u8> को &[u8] में? और उल्टा?»। यह Stack Overflow पर सबसे लोकप्रिय प्रश्नों में से एक है (दसियों हज़ार व्यूज़), और यह कोई संयोग नहीं है। सरल दिखने वाले रूपांतरणों में छिपे हुए खतरे होते हैं, खासकर जब प्रदर्शन की बात आती है।
इस लेख में हम केवल «कैसे करें» के तरीकों को सूचीबद्ध नहीं करेंगे। हम यह समझेंगे कि क्यों कुछ विधियाँ दूसरों की तुलना में तेज़ हैं, और प्रत्येक का उपयोग कब करना चाहिए। आप सीखेंगे कि अनावश्यक कॉपी, अतिरिक्त आवंटन से कैसे बचें और Rust में वास्तव में कुशल कोड कैसे लिखें।
\n\nयह क्यों जानना चाहिए? संदर्भ और प्रदर्शन
\nRust एक ऐसी भाषा है जो आपको मेमोरी पर नियंत्रण देती है। लेकिन नियंत्रण के साथ जिम्मेदारी भी आती है। स्ट्रिंग्स और बाइट्स के बीच रूपांतरण सबसे सामान्य ऑपरेशनों में से एक है। उदाहरण के लिए, नेटवर्क प्रोटोकॉल, डेटा सीरियलाइज़ेशन (JSON, Protobuf) या केवल फ़ाइलों को पढ़ने के साथ काम करते समय। रूपांतरण का गलत चुनाव इसका कारण बन सकता है कि आप उस डेटा को कॉपी कर लें जिसे आप बिना कॉपी किए उपयोग कर सकते थे। सिस्टम प्रोग्रामिंग की दुनिया में यह महत्वपूर्ण है।
\n\nआइए चार मुख्य प्रकारों को समझें और बिना नुकसान के उनके बीच उड़ना सीखें।
\n\nString और &str: एक ही सिक्के के दो पहलू
\nString एक स्वामित्व वाली, परिवर्तनीय, UTF-8 स्ट्रिंग है। &str एक उधार लिया गया, अपरिवर्तनीय स्लाइस (slice) है। मुख्य नियम: String डेटा का मालिक है, &str डेटा का संदर्भ है।
String से &str कैसे प्राप्त करें (और इसके विपरीत)
\nयह सबसे सरल और सुरक्षित मामला है।
\n\nlet my_string = String::from("नमस्ते, दुनिया!");\n// 1. String से &str प्राप्त करें (बस उधार लें)\nlet my_str: &str = &my_string;\n// या as_str() का उपयोग करके\nlet my_str2: &str = my_string.as_str();\n\n// 2. &str से String प्राप्त करें (एक नई प्रतिलिपि बनाएँ)\nlet new_string: String = my_str.to_string();\n// या\nlet new_string2: String = String::from(my_str);\n\nमहत्वपूर्ण: &str को String में बदलना हमेशा नई आवंटित मेमोरी (एलोकेशन) बनाता है। यह महंगा है। String को &str में बदलना केवल एक संदर्भ लेना है (मुफ्त)।
String से Vec<u8> कैसे प्राप्त करें (और इसके विपरीत)
\nयहाँ से दिलचस्प शुरुआत होती है, क्योंकि String आंतरिक रूप से केवल एक Vec<u8> है जिसमें सही UTF-8 की गारंटी होती है।
let my_string = String::from("Rust");\n\n// 3. String -> Vec<u8>\n// विकल्प A (कॉपी करना): सुरक्षित, लेकिन महंगा\nlet bytes_vec_copy: Vec<u8> = my_string.as_bytes().to_vec();\n\n// विकल्प B (बिना कॉपी किए, String का उपभोग):\nlet bytes_vec_owned: Vec<u8> = my_string.into_bytes(); // my_string अब मौजूद नहीं है!\n\n// 4. Vec<u8> -> String (UTF-8 सत्यापन)\nlet new_string: String = String::from_utf8(bytes_vec_owned).expect("अमान्य UTF-8");\n// यदि आप वैधता के प्रति आश्वस्त हैं:\nlet new_string_unchecked: String = unsafe { String::from_utf8_unchecked(bytes_vec_copy) };\n\nमुख्य बिंदु: into_bytes() एक शून्य-लागत रूपांतरण है। यह आंतरिक बफर Vec<u8> लेता है और इसे आपको देता है, बिना एक भी बाइट कॉपी किए। as_bytes().to_vec() एक स्पष्ट कॉपी है।
विधि from_utf8_unchecked unsafe है। इसका उपयोग केवल तभी करें जब आप 100% आश्वस्त हों कि बाइट्स वैध UTF-8 हैं। अन्यथा, प्रोग्राम पैनिक के साथ क्रैश हो सकता है या, इससे भी बदतर, UB (अपरिभाषित व्यवहार) हो सकता है।