Rust [डुप्लिकेट] में & str को कैसे करें

Oct 19 2020

यह देखते हुए कि मैं मान रहा हूं कि हेक्साडेसिमल में एक अयस्क अधिक दशमलव है, मैं इसे बाइट्स में बदलने के लिए_____ से कॉल करने की कोशिश कर रहा हूं। हालाँकि, from_str_radix को उम्मीद है कि वे अभी भी नहीं हैं। क्या प्रत्येक और char को & str में बदलने का कोई तरीका है?

fn convertCharsToBytes(args: &[char]) -> std::vec::Vec<u8> {
    let mut bytes:Vec<u8> = Vec::new();
    for arg in args {
        let byte = u8::from_str_radix(arg, 16); //arg here is invalid as it is a &char, not a &str
        match byte {
            Ok(value) => bytes.push(value),
            Err(error) => {}
        }
    }
    println!("{:?}", bytes);
    return bytes;
}

जवाब

1 asmmo Oct 20 2020 at 05:06

मुझे लगता है कि यह उम्मीद के मुताबिक काम करेगा

fn convertCharsToBytes(args: &[char]) -> std::vec::Vec<u8> {
    let mut bytes:Vec<u8> = Vec::new();
    for arg in args {
        let byte = u8::from_str_radix(&arg.to_string(), 16);
        match byte {
            Ok(value) => bytes.push(value),
            Err(error) => ()
        }
    }
    println!("{:?}", bytes);
    return bytes;
}

&arg.to_string() उत्पन्न स्ट्रिंग का एक टुकड़ा है जिसमें एक चार होते हैं।

Jmb Oct 20 2020 at 07:16

आप स्वयं रूपांतरण करके अतिरिक्त आवंटन से बच सकते हैं:

let byte = if char > 'a' { char as u32 - 'a' as u32 }
           else if char > 'A' { char as u32 - 'A' as u32 }
           else { char as u32 - '0' as u32 } as u8;

प्लस त्रुटि की जाँच करें कि क्या आप यह गारंटी नहीं दे सकते कि चार वैध हेक्साडेसिमल अंक है।

ध्यान दें कि यह (साथ ही साथ आपका मूल कोड) प्रत्येक चार्ट को व्यक्तिगत रूप से परिवर्तित करेगा। इसलिए यदि आप इसे कहते हैं "1a", तो bytesइसमें शामिल होगा [0x01, 0x0a]और नहीं [0x1a] ।

AngelicosPhosphoros Oct 20 2020 at 06:48

थोड़ा तेज:

fn convertCharsToBytes(args: &[char]) -> std::vec::Vec<u8> {
    // E.g. 17 is encoded as 0x11 but 10 as 0x0A
    // So bytes are always encoded using 2 symbols
    assert_eq!(args.len()%2, 0, "Hexes length must be even!");
    let mut bytes:Vec<u8> = Vec::with_capacity(args.len()/2);
    // To reuse allocation instead calling to_string on every iteration
    let mut string = String::new();
    for &num in args.chunks_exact(2) {
        // To eliminate bounds checks in indexing
        // Maybe in future chunks_exact would return &[T;2] instead of &[T]
        // but it is inaccessible before const generics
        assert_eq!(num.len()==2);
        string.clear();
        string.push(num[0]);
        string.push(num[1]);
        let byte = u8::from_str_radix(&string, 16);
        match byte {
            Ok(value) => bytes.push(value),
            Err(_) => panic!("Invalid hex {}!", &string),
        }
    }
    println!("{:?}", bytes);
    return bytes;
}

या, यदि आप O (n) अतिरिक्त मेमोरी उपयोग और पुलिंग निर्भरता की परवाह नहीं करते हैं :

fn convertCharsToBytes(args: &[char]) -> std::vec::Vec<u8> {
    let s: String = args.iter().collect();
    let bytes = hex::decode(&s).expect("Failed to parse hex");
    println!("{:?}", bytes);
    return bytes;
}

UPD: पहले कोड में फिक्स्ड त्रुटि छिन गई (मैं भूल गया, कि एक बाइट 1 वर्ण द्वारा एन्कोडेड है)। इस तरह की त्रुटियां यही कारण है कि आपको क्रेट के बेहतर परीक्षण के बाद खुद के समाधान के बजाय निर्भरता का उपयोग करना चाहिए।