如何取消结构的大小



我在Rust中的数据布局的心理模型是,所有结构的大小都必须在编译时已知,这意味着它们的所有属性都必须在汇编时递归已知。这就是为什么你不能有一个仅仅是特征的结构成员(以及为什么必须使用枚举来代替并集类型(:大小是未知的,所以你必须使用

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

但在Path的文档中,它说:

这是一个无大小的类型,意味着它必须始终在像&Box这样的指针后面使用。有关此类型的自有版本,请参见PathBuf

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

我的心理模型有什么问题,认为这是可能的?

我找到了关于什么是动态大小的类型的解释,但我仍然不明白如何制作自己的类型。这样做是为语言本身保留的特殊特权吗?

一个结构允许包含一个未大小的字段,这会使结构本身不大小。构造未大小类型的值可能非常困难,通常只能通过使用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是保证为有效utf-8的&[u8]一样。

最新更新