本文介绍了将数字原语(i32、f64 等)转换为字节表示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个库,用于将数据编码/解码为二进制格式.部分格式是数字,我使用 Rust 的原生原始类型(例如 i8i64f32 等).

I am writing a library that encodes/decodes data to/from a binary format. Part of the format is numbers, which I'm using Rust's native primitive types for (like i8, i64, f32 etc.).

是否有一种简单的内置方法将这些数据类型转换为二进制或从二进制转换,即转换 f64/f32/i64/等.变成 Vec?同样,有没有办法将 4 个 u8(在 Vec 中)转换为 f32?

Is there an easy, built-in way to convert these data types into/from binary, i.e. convert a f64/f32/i64/etc. into a Vec<u8>? Likewise is there a way to convert 4 u8s (in a Vec<u8> say) into an f32?

推荐答案

不幸的是,目前在 Rust 中没有安全的内置支持从/向字节数组读取/写入原语.有几个社区库,但是,byteorder 是最常用的:

Unfortunately, there is no safe built-in support for reading/writing primitives from/to a byte array in Rust at the moment. There are several community libraries for that, however, byteorder being the most used one:

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 并且由于字节顺序而依赖于平台,因此只能作为最后的手段使用:

Of course, you can always cast raw pointers. For example, you can turn *const i64 into *const i8 and then convert it into an appropriate byte slice &[u8]. However, this is easy to get wrong, unsafe and platform-dependent due to endiannness, so it should be used only as a last resort:

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

这篇关于将数字原语(i32、f64 等)转换为字节表示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 05:12