Cómo convertir & char a & str en Rust [duplicar]
Dado un argumento & [char], que supongo que es uno o más decimales en hexadecimal, estoy tratando de llamar a from_str_radix para convertirlo en bytes. Sin embargo, from_str_radix espera & str no & char. ¿Hay alguna forma de convertir cada & char en & 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;
}
Respuestas
Creo que esto funcionará como se esperaba.
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() es una porción de la cadena generada que consta de un carácter.
Puede evitar asignaciones adicionales si realiza la conversión usted mismo:
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;
Además de la comprobación de errores si no puede garantizar que char sea un dígito hexadecimal válido.
Sin embargo, tenga en cuenta que esto (así como su código original) convertirá cada carácter individualmente. Entonces, si lo llama con "1a", bytescontendrá [0x01, 0x0a]y no [0x1a] .
Un poco más rápido:
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, si no le importa O (n) uso de memoria adicional y dependencia de extracció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: Se corrigió el error en el primer código recortado (lo olvidé, que un byte está codificado por 1 carácter). Este tipo de errores es la razón por la que debe usar la dependencia en lugar de codificar la propia solución, ya que la caja se prueba mucho mejor.