繁体   English   中英

Rust,如何像浮点数组一样切片成字节数组?

[英]Rust, how to slice into a byte array as if it were a float array?

我在&[u8]中有一些字节数据,我知道切片中包含的数据是浮点数据。 我想做相当于auto float_ptr = (float*)char_ptr;

我试过了:

let data_silce = &body[buffer_offset..(buffer_offset + buffer_length)] as &[f32];

但是你不能在 rust 中执行这种类型的转换。

您将需要使用 unsafe Rust 来解释一种类型的数据,就好像它是另一种类型的数据一样。

你可以做:

let bytes = &body[buffer_offset..(buffer_offset + buffer_length)];

let len = bytes.len();
let ptr = bytes.as_ptr() as *const f32;
let floats: &[f32] = unsafe { std::slice::from_raw_parts(ptr, len / 4)};

请注意,如果其中任何一个为真,则这是未定义的行为:

  • 原始切片的大小不是 4 字节的倍数
  • 切片的 alignment 不是 4 字节的倍数

所有 4 个字节的序列都是有效的f32 s,但是对于没有该属性的类型,为了避免 UB,您还需要确保所有值都是有效的。

使用bytemuck库; 特别是bytemuck::cast_slice() 下面,它只是其他答案中已经描述的不安全转换,但它使用编译时(类型)和运行时(长度和对齐)检查来确保不必担心正确检查安全条件。

let data_slice: &[f32] = bytemuck::cast_slice(
    &body[buffer_offset..(buffer_offset + buffer_length)
];

请注意,如果切片的开头和结尾未与 4 个字节对齐,则会出现恐慌。 在 Rust 中无法避免此要求 — 如果数据未对齐,则必须将其复制到已对齐的新位置。 (由于您的目标是生成f32 ,在确保 alignment 的同时,最简单的方法是使用f32::from_ne_bytes()进行迭代,执行f32转换复制。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM