我有一个大小未知的字节缓冲区,我想创建一个局部 struct 变量,指向缓冲区开头的内存.按照我在C语言中所做的,我在Rust中try 了很多不同的东西,并且不断出现错误.这是我的最新try :

use std::mem::{size_of, transmute};

#[repr(C, packed)]
struct MyStruct {
    foo: u16,
    bar: u8,
}

fn main() {
    let v: Vec<u8> = vec![1, 2, 3];
    let buffer = v.as_slice();
    let s: MyStruct = unsafe { transmute(buffer[..size_of::<MyStruct>()]) };
}

我得到一个错误:

error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
   --> src/main.rs:12:42
    |
12  |     let s: MyStruct = unsafe { transmute(buffer[..size_of::<MyStruct>()]) };
    |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `[u8]`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>

推荐答案

如果不想将数据复制到 struct 中,而是将其保留在原位,可以使用slice::align_to.这将创建一个&MyStruct:

#[repr(C, packed)]
#[derive(Debug, Copy, Clone)]
struct MyStruct {
    foo: u16,
    bar: u8,
}

fn main() {
    let v = vec![1u8, 2, 3];

    // I copied this code from Stack Overflow
    // without understanding why this case is safe.
    let (head, body, _tail) = unsafe { v.align_to::<MyStruct>() };
    assert!(head.is_empty(), "Data was not aligned");
    let my_struct = &body[0];

    println!("{:?}", my_struct);
}

在这里,使用align_to可以安全地将一些字节转换为MyStruct,因为我们使用了repr(C, packed)MyStruct中的所有类型都可以是任意字节.

另见:

Rust相关问答推荐

在自身功能上实现类似移动的行为,以允许通过大小的所有者进行呼叫(&;mut;self)?

关于如何初始化弱 struct 字段的语法问题

通过解引用将值移出Box(以及它被脱糖到什么地方)?

如何计算迭代器适配器链中过滤的元素的数量

一种随机局部搜索算法的基准(分数)

rust 蚀生命周期 不匹配-不一定超过此处定义的生命周期

Rust函数的返回值不能引用局部变量或临时变量

从管道读取后重置标准输入

要求类型参数有特定的大小?

当我try 使用 SKI 演算中的S I I实现递归时,为什么 Rust 会失败?

`use` 和 `crate` 关键字在 Rust 项目中效果不佳

我可以禁用发布模式的开发依赖功能吗?

Option<&T> 如何实现复制

go 重并堆积MPSC通道消息

在 Bevy 项目中为 TextureAtlas 精灵实施 NearestNeighbor 的正确方法是什么?

具有在宏扩展中指定的生命周期的枚举变体数据类型

n 个范围的笛卡尔积

为什么在 macOS / iOS 上切换 WiFi 网络时 reqwest 响应会挂起?

TinyVec 如何与 Vec 大小相同?

返回 &str 但不是 String 时,borrow 时间比预期长