我正在编写一个库,用于对二进制格式的数据进行编码/解码.格式的一部分是数字,我使用锈病的本地原始类型(如i8,i64,f32等).
是否有这些数据类型转换成/二进制,即转换为一个简单的,内置的方式f64/ f32/ i64/等.变成了Vec<u8>?同样有没有办法将4 u8秒(在一个Vec<u8>说法中)转换为f32?
Nic*_*hel 27
从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);
Run Code Online (Sandbox Code Playgroud)
对于浮点,您仍然必须依靠先前的方法。
Vla*_*eev 21
不幸的是,目前没有安全的内置支持从Rust中读取/写入一个字节数组的原语.有几个社区库,但是,字节顺序是最常用的:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
当然,你总是可以投射原始指针.例如,你可以把*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);
}
}
Run Code Online (Sandbox Code Playgroud)
F00*_*001 15
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);
}
}
Run Code Online (Sandbox Code Playgroud)
注意:请确保两个变量的大小完全相等.
以尼古拉斯·里舍尔(Nicholas Rishel)的答案为基础。
拉斯特1.32有:{to,from}_{ne,le,be}_bytes,to_bits,和from_bits。
将整数转换为字节然后返回:
let x = 65535_i32;
let x_bytes = x.to_ne_bytes(); // x_bytes = [255, 255, 0, 0] or [0, 0, 255, 255]
let original_x = i32::from_ne_bytes(x_bytes); // original_x = 65535 = x
Run Code Online (Sandbox Code Playgroud)
将浮点数转换为字节然后返回:
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
Run Code Online (Sandbox Code Playgroud)
根据Rust文档from_bits可能存在可移植性问题。
Rust每晚{to,from}_{ne,le,be}_bytes为浮点类型添加:issue。
将浮点数转换为字节,然后返回(每晚):
#![feature(float_to_from_bytes)]
let y = 255.255_f64;
let y_bytes = y.to_ne_bytes();
let original_y = f64::from_ne_bytes(y_bytes); // original_y = 255.255 = y
Run Code Online (Sandbox Code Playgroud)