Sto cercando di imparare Rust e ho deciso di scrivere un programma che converta una stringa esadecimale in un u64.Qual è il modo più appropriato per convertire i nibbles in un u64?
Attualmente, ho analizzato la stringa in un vettore di valori u8, ciascuno rappresentante quattro bit (o "nibble"). Ho scritto il seguente codice per prendere uno Vec<u8>
e restituire uno u64
corrispondente. Funziona (per quanto riguarda i miei test), ma non sono sicuro che sia il modo "appropriato" in Rust per fare questo.
fn convert_nibbles_to_u64(values: &Vec<u8>) -> u64 {
// We need to turn this buffer into a u64 now
let mut temp:u64 = 0;
for i in values {
temp = temp << 4;
unsafe {
// We need to unsafely convert a u8 to a u64. Note that
// the host endian-ness will matter here.
use std::mem;
let i_64_buffer = [0u8,0u8,0u8,0u8,0u8,0u8,0u8,i.clone()];
let i_64 = mem::transmute::<[u8; 8], u64>(i_64_buffer);
let i_64_be = u64::from_be(i_64);
temp = temp | i_64_be;
}
}
return temp;
}
Suppongo che il problema principale non so in quale altro modo per lanciare un u8
ad un valore u64
. Potresti commentare i modi per migliorare o scrivere il codice in uno stile più idiomatico e simile alla Ruggine?
EDIT: Ho provato le seguenti alternative (falliti) al blocco pericoloso:
Or'ing con i
come u64
:
temp = temp | i as u64;
------
Compiler error:
main.rs:115:23: 115:31 error: non-scalar cast: `&u8` as `u64`
main.rs:115 temp = temp | i as u64;
Or'ing con i
direttamente:
temp = temp | i;
------
Compiler error:
main.rs:115:16: 115:24 error: the trait `core::ops::BitOr<&u8>` is not implemented for the type `u64` [E0277]
main.rs:115 temp = temp | i;
Cosa c'è di sbagliato con 'i come u64'? –
Quindi, da ogni 'u8' stai usando solo quattro bit. Quindi se i tuoi bit sono '[0b0000AAAA, 0b0000BBBB, 0b0000CCCC, 0b0000DDDD, 0b0000EEEE, 0b0000FFFF, 0b0000GGGG, 0b0000HHHH]' stai per finire con '0bAAAABBBBCCCCDDDDEEEEFFFFGGGHHHHu64'. Ho ragione? –
@ChrisMorgan se l'input è [0xF, 0xE, 0xE, 0xD, 0xB, 0xE, 0xE, 0xF, 0xF, 0xE, 0xE, 0xD, 0xB, 0xE, 0xE, 0xF], l'output deve essere 0xFEEDBEEFFEEDBEEFu64. – samoz