我正在写一个库,它可以对二进制格式的数据进行编码/解码.格式的一部分是数字,我使用Rust的原生原始类型(比如i8i64f32等).

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

推荐答案

不幸的是,目前还没有安全的内置支持从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].然而,这很容易出错,而且由于端性而依赖于平台,因此只能作为最后手段使用:

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

Rust相关问答推荐

如何在Rust中在屏幕中间打印内容?

当Option为None时,Option数组是否占用Rust中的内存?

编译项目期间使用Cargo生成时出现rustc错误

如何在 struct 的自定义序列化程序中使用serde序列化_WITH

如何删除Mac Tauri上的停靠图标?

在铁 rust 中传递所有权

用于判断整数块是否连续的SIMD算法.

将 &str 或 String 保存在变量中

有没有办法隐式绑定 let/match 操作的成员?

在线程中运行时,TCPListener(服务器)在 ip 列表中的服务器实例之前没有从客户端接受所有客户端的请求

打印 `format_args!` 时borrow 时临时值丢失

RAII 模式的 Rust 解决方案,用于在 new() 和 drop() 上修改另一个对象

仅当满足外部条件时如何添加到 actix web 的路由

Rust 中的let是做什么的?

当 `T` 没有实现 `Debug` 时替代 `unwrap()`

TcpStream::connect - 匹配武器具有不兼容的类型

为什么我可以在没有生命周期问题的情况下内联调用 iter 和 collect?

Rust 生命周期:不能在方法内重新borrow 可变字段

如何重写这个通用参数?

如何在宏中的多个参数上编写嵌套循环?