memory - 如何调整结构体的大小?

标签 memory struct rust

我对 Rust 中数据布局的心理模型是,所有结构体的大小都必须在编译时已知,这意味着它们的所有属性都必须在编译时递归地知道。这就是为什么你不能拥有一个只是一个特征的结构成员(以及为什么必须使用枚举来代替联合类型):大小无法知道,所以你必须使用其中之一

  1. 泛型,因此该特征在使用时会“具体化”为大小已知的结构
  2. 一个枚举,具有一组有限的可能大小已知的布局
  3. 一个Box ,其大小已知,因为它只是一个指针

但是在 Path 的文档中,它说:

This is an unsized type, meaning that it must always be used behind a pointer like & or Box. For an owned version of this type, see PathBuf.

然而Path既不是特征也不是通用结构,它只是一个普通的结构。

我认为这可能的思维模式出了什么问题?

我找到了this explanation of what dynamically-sized types are ,但我仍然不明白,我将如何制作自己的一个。这样做是为语言本身保留的特殊特权吗?

最佳答案

结构体可以包含单个未调整大小的字段,这使得结构体本身未调整大小。构造未调整大小的类型的值可能非常困难,通常只能通过使用 unsafe 将对已调整大小的变体的引用转换为未调整大小的变体来完成。

例如,可以使用 #[repr(transparent)]使得可以像这样将 &[u8] 转换为 &MySlice 。此属性使类型保证以与其单个字段相同的方式表示。

#[repr(transparent)]
struct MySlice {
    inner: [u8],
}

像这样转换切片是合理的:

impl MySlice {
    pub fn new(slice: &[u8]) -> &MySlice {
        // SAFETY: This is ok because MySlice is #[repr(transparent)]
        unsafe {
            &*(slice as *const [u8] as *const MySlice)
        }
    }
}

你可以例如如果切片不是有效的 ascii,则拒绝执行转换,现在您将拥有一个保证指向有效 ascii 的字节数组,就像 &str&[u8] 保证是有效的 utf-8。

关于memory - 如何调整结构体的大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61293115/

相关文章:

c++ - 输入结构体中数组的大小

c++ - 使用匿名结构初始化会在堆栈上放置额外的拷贝吗?

rust - 如何消除关联类型的歧义?

winapi - 如何使用 winapi crate 为 Windows 制作托盘图标?

c++ - 堆已通过代码在多个地方损坏

java - Java中的垃圾收集

java - JMeter 清除 JDBC 响应数据

c - 免费 GSL 矩阵的正确方法是什么?

将 struct 转换为 int

rust - 将枚举转换为 BTreeMap?