Преобразование числовых примитивов (i32, f64 и т. д.) В байтовые представления
Я пишу библиотеку, которая кодирует / декодирует данные в / из двоичного формата. Часть формата-это числа, для которых я использую собственные примитивные типы Rust (например i8
, i64
, f32
и т.д.).
Существует ли простой, встроенный способ преобразования этих типов данных в / из двоичных, т. е. f64
/f32
/i64
/и т.д. в Vec<u8>
? Точно так же есть способ преобразовать 4 u8
s (в Vec<u8>
скажем) в f32
?
3 ответа:
К сожалению, в настоящее время в Rust нет безопасной встроенной поддержки чтения/записи примитивов из/в байтовый массив. Для этого есть несколько библиотек сообщества, однако byteorder является наиболее используемым:
extern crate byteorder; use byteorder::{LittleEndian, WriteBytesExt}; use std::mem; fn main() { let i: i64 = 12345; let mut bs = [0u8; mem::size_of::<i64>()]; bs.as_mut() .write_i64::<LittleEndian>(i) .expect("Unable to write"); for i in &bs { println!("{:X}", i); } }
Конечно, вы всегда можете использовать необработанные указатели. Например, вы можете превратить
*const i64
в*const i8
, а затем преобразовать его в соответствующий байтовый фрагмент&[u8]
. Тем не менее, это легко получить неправильно,unsafe
и зависит от платформы из-за endiannness, так что это должно быть используется только в крайнем случае:use std::{mem, slice}; fn main() { let i: i64 = 12345; let ip: *const i64 = &i; let bp: *const u8 = ip as *const _; let bs: &[u8] = unsafe { slice::from_raw_parts(bp, mem::size_of::<i64>()) }; for i in bs { println!("{:X}", i); } }