मैं बाइट्स (u8) के वेक्टर को स्ट्रिंग में कैसे परिवर्तित करूं


94

मैं रूस्ट में साधारण टीसीपी / आईपी क्लाइंट लिखने की कोशिश कर रहा हूं और मुझे सर्वर से प्राप्त बफर को प्रिंट करने की आवश्यकता है।

मैं a Vec<u8>(या a &[u8]) को a में कैसे परिवर्तित करूं String?

जवाबों:


98

बाइट्स के एक स्लाइस को स्ट्रिंग स्लाइस (UTF-8 एन्कोडिंग मानकर) में परिवर्तित करने के लिए:

use std::str;

//
// pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error>
//
// Assuming buf: &[u8]
//

fn main() {

    let buf = &[0x41u8, 0x41u8, 0x42u8];

    let s = match str::from_utf8(buf) {
        Ok(v) => v,
        Err(e) => panic!("Invalid UTF-8 sequence: {}", e),
    };

    println!("result: {}", s);
}

रूपांतरण में जगह है, और एक आवंटन की आवश्यकता नहीं है। आप Stringस्ट्रिंग स्लाइस से बना सकते हैं यदि स्ट्रिंग स्लाइस .to_owned()पर कॉल करके ( अन्य विकल्प उपलब्ध हैं )।

रूपांतरण समारोह के लिए पुस्तकालय संदर्भ:


आप जोड़ना चाह सकते हैं कि यह संभव है क्योंकि
Vec

हालांकि उदाहरण कोड वास्तव में एक वेक्टर :-) का उपयोग नहीं करता है
एंड्रयू मैकेंजी

हालाँकि यह सच है कि from_utf8यह आवंटित नहीं होता है, लेकिन यह उल्लेखनीय है कि इसे utf-8 शुद्धता को मान्य करने के लिए डेटा को स्कैन करने की आवश्यकता है। तो यह एक ओ (1) ऑपरेशन नहीं है (जो पहले सोच सकता है)
जर्गनी

64

मैं पसंद करता हूं String::from_utf8_lossy:

fn main() {
    let buf = &[0x41u8, 0x41u8, 0x42u8];
    let s = String::from_utf8_lossy(buf);
    println!("result: {}", s);
}

यह अमान्य UTF-8 बाइट्स को It में बदल देता है और इसलिए किसी भी त्रुटि से निपटने की आवश्यकता नहीं है। यह तब अच्छा होता है जब आपको इसकी आवश्यकता नहीं होती है और मुझे इसकी आवश्यकता होती है। आप वास्तव में इससे प्राप्त Stringकरते हैं। यह प्रिंट करना चाहिए कि आपको सर्वर से क्या आसान हो रहा है।

कभी-कभी आपको into_owned()विधि का उपयोग करने की आवश्यकता हो सकती है क्योंकि यह लिखने पर क्लोन होता है।


3
into_owned()सुझाव के लिए बहुत बहुत धन्यवाद ! क्या वास्तव में मैं देख रहा था (यह एक उचित बन जाता है Stringजिसे आप एक विधि से वापसी मान के रूप में वापस कर सकते हैं, उदाहरण के लिए)।
प्रति लुंडबर्ग

48

यदि आपके पास वास्तव में बाइट्स का वेक्टर है ( Vec<u8>) और a में कनवर्ट करना चाहते हैं String, तो सबसे अधिक प्रभावी आवंटन के साथ पुन: उपयोग करना है String::from_utf8:

fn main() {
    let bytes = vec![0x41, 0x42, 0x43];
    let s = String::from_utf8(bytes).expect("Found invalid UTF-8");
    println!("{}", s);
}

2
धन्यवाद! अन्य दो उत्तरों ने प्रश्न को अनदेखा क्यों किया?
जेहन

1
@ जेहन क्योंकि लोग आम तौर पर सवाल पूछने में अच्छे नहीं होते हैं, खासकर जब वे किसी भाषा में नए हों। जंग एक सरणी , एक टुकड़ा और एक के बीच एक अंतर बनाती है Vec, लेकिन नए लोगों को मतभेद नहीं पता है। सभी सवालों और जवाबों को उभारना सुनिश्चित करें जो हालांकि उपयोगी साबित होते हैं।
Shepmaster

ध्यान दें कि जैसा कि @ ब्योर्न टिपलिंग द्वारा उल्लेख किया गया है आप String::from_utf8_lossyयहां इसके बजाय उपयोग कर सकते हैं , फिर आपको अपेक्षित कॉल की आवश्यकता नहीं है।
जेम्स रे

2
संपादित करें: ध्यान दें कि जैसा कि @ ब्योर्न टिपिंग द्वारा बताया गया है कि आप सोच सकते हैं कि आप String::from_utf8_lossyयहां इसके बजाय उपयोग कर सकते हैं , फिर आपको expectकॉल की आवश्यकता नहीं है , लेकिन उस पर इनपुट बाइट्स ( &'a [u8]) का एक टुकड़ा है । OTOH, वहाँ भी है from_utf8_unchecked। "यदि आप सुनिश्चित हैं कि बाइट स्लाइस UTF-8 मान्य है, और आप रूपांतरण के ओवरहेड को लाइक नहीं करना चाहते हैं, तो इस फ़ंक्शन का एक असुरक्षित संस्करण है [ from_utf8_lossy],] from_utf8_unchecked, जिसमें एक ही व्यवहार है लेकिन चेक को छोड़ देता है। "
जेम्स रे

ध्यान दें कि आप &vec_of_bytesबाइट्स के एक स्लाइस में वापस बदलने के लिए उपयोग कर सकते हैं , जैसा कि उदाहरणों में सूचीबद्ध है from_utf8_lossydoc.rust-lang.org/std/string/…
जेम्स रे
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.