2015-04-04 4 views
9

Sto scrivendo una libreria che codifica/decodifica le cose da/verso un formato binario. Parte del formato sono i numeri, che sto usando per i tipi primitivi nativi di Rust (come i8, i64, f32 ecc.). Esiste un modo semplice e integrato per convertire questi tipi di dati in/da binari, ovvero Convertire un f64/i64/ecc. in un Vec<u8>? Allo stesso modo c'è un modo per convertire 4 u8 's (in un Vec<u8>' s dire) in un f32?Conversione di primitive numeriche (i32, f64, ecc.) In rappresentazioni di byte

risposta

9

Sfortunatamente, al momento non esiste un supporto integrato sicuro per la lettura/scrittura di primitive da/a un array di byte in Rust. Esistono diverse librerie di comunità, tuttavia, byteorder è il più utilizzato. Ti suggerisco di provarlo.

Naturalmente, si può sempre lanciare puntatori prime, così, ad esempio, è possibile trasformare in *const i64*const i8 e quindi convertirlo in una fetta di byte appropriato &[u8]. Tuttavia, questo è facile da sbagliare, unsafe e dipendente dalla piattaforma, quindi dovrebbe essere utilizzato solo come ultima risorsa:

use std::mem; 
use std::slice; 

let i: i64 = 12345; 
let ip: *const i64 = &x; 
let bp: *const u8 = ip as *const _; 
let bs: &[u8] = unsafe { 
    slice::from_raw_parts(
     bp, 
     mem::size_of::<i64>() 
    ) 
}; 
+2

Utilizzando 'std: : slice :: from_raw_parts' è meno codice e anche contrassegnato come stabile. Ancora insicuro per gli stessi motivi, però! – bluss

+0

@ user139873, ooh, bello, in qualche modo ho perso che tale funzione esiste. Ho aggiornato la risposta. –

+2

'byteorder' lo risolve esattamente. Quando ho detto "integrato" avrei dovuto specificare che qualcosa da casse.io sarebbe stato sufficiente. – Rory

9

std::mem::transmute è stabile ora, anche se è unsafe. Siamo in grado di fare qualcosa di simile:

fn main() { 
    let var1 = 12345678_i64; 
    let raw_bytes : [i8; 8] = unsafe {std::mem::transmute(var1)}; 
    for byte in &raw_bytes { 
     println!("{}", byte); 
    } 
} 

Nota: Si prega di essere sicuri che la dimensione delle due variabili sono esattamente uguali.

0

Se il vostro obiettivo è quello di stampare i byte o li hanno in una rappresentazione str, è sufficiente utilizzare la notazione :b in un formato doppietta

fn main() { 
    println!("This is the binary of int {:b}", 4 as i32); 
} 

Questo stampa

This is the binary of int 100

Problemi correlati