将数字基元(i32,f64等)转换为字节表示

时间:2015-04-04 09:55:49

标签: types rust

我正在编写一个库,用于对二进制格式的数据进行编码/解码。部分格式是数字,我正在使用Rust的原始基本类型(如i8i64f32等。)

是否有一种简单的内置方法可以将这些数据类型转换为二进制数据,或者转换为f64 / f32 / i64 /等。变成Vec<u8>?同样,有一种方法可以将4个u8(在Vec<u8>中说)转换为f32吗?

5 个答案:

答案 0 :(得分:19)

不幸的是,目前还没有安全的内置支持从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]。但是,由于endiannness,这很容易出错,unsafe和平台相关,因此它应该仅作为最后的手段使用:

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);
    }
}

答案 1 :(得分:13)

可以使用

std::mem::transmute,但它是unsafe

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

注意:请确保两个变量的大小完全相同。

答案 2 :(得分:6)

从Rust 1.32开始,您可以将{to,from}_{ne,le,be}_bytes用于整数类型。

let begin = 1234_i32;
let bytes = begin.to_ne_bytes();
let and_back = i32::from_ne_bytes(bytes);

对于浮点,您仍然必须依靠先前的方法。

答案 3 :(得分:2)

Nicholas Rishel's answer为基础。

Rust 1.32具有:{to,from}_{ne,le,be}_bytesto_bitsfrom_bits

将整数转换为字节然后返回:

let x = 65535_i32;
let x_bytes = x.to_ne_bytes();                  // x_bytes = [255, 255, 0, 0]
let original_x = i32::from_ne_bytes(x_bytes);   // original_x = 65535 = x

将浮点数转换为字节然后返回:

let y = 255.255_f64;
let y_bytes = y.to_bits().to_ne_bytes();
let original_y = f64::from_bits(u64::from_ne_bytes(y_bytes)); // original_y = 255.255 = y

根据Rust文档from_bits可以有portability issues

答案 4 :(得分:-1)

如果您的目标是打印字节或以str表示形式使用它们,只需在格式大括号中使用:b表示法

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

打印

This is the binary of int 100