compiler-errors - 包含具有特征参数的结构的框的大小
问题描述
我需要一个包含特征对象及其本身的结构。令人失望的是,以下代码无法编译:
trait Foo {}
struct Bar<T: Foo> {
bars: Vec<Box<Bar<dyn Foo>>>,
foo: T,
}
?Sized
我设法通过添加绑定来强制编译T
,但我不明白为什么会这样。我认为这是因为所有 trait 对象都具有相同的大小,但 的大小Bar
取决于具体类型的大小T
。如果是这样,如何在内存中表示Bar
一个未调整大小的?T
特别是在堆上跟踪它的大小以及为什么不能在大小调整的情况下使用这种机制。
解决方案
该类型dyn Foo
在编译时没有已知的大小。因此,当您编写 时Bar<dyn Foo>
,编译器将不允许这样做,因为(默认情况下)类型参数必须调整大小。编译器建议您通过允许未调整大小来解决此问题,这对于beT
是必需的。T
dyn Foo
内存中没有大小
Bar
的表示如何?T
一个结构最多允许有一个未调整大小的字段。然后它的数据首先在内存中布局,首先是大小字段,然后是未大小字段。这个限制意味着所有字段的相对内存地址可以在编译时知道。具有?Sized
类型参数的结构本身可以调整大小或不调整大小,具体取决于其参数的具体类型。当结构未调整大小时,它不能进入堆栈,因此您只能从指针后面使用它。
目前没有此类对象的文档。它不完全是一个特征对象,但它是一个指向可能没有调整大小的东西的指针。正如您的示例所示,这有效。但是我不能告诉你vtable
指针存储在哪里,因为我不知道,我不知道如何找到。
特别是在堆上跟踪它的大小以及为什么不能在大小调整的情况下使用这种机制。
每个对象的大小实际上并没有改变——只是每个实例可能不同。该机制可以“在Sized
案例中”使用,但您没有大小合适的案例!即使T
是大小合适的,bars
集合也将包含未调整大小的盒子Bar<dyn Foo>
。这就是为什么您需要T: ?Sized
(而不是T: !Sized
)来说明这种类型适用于T
调整大小或不调整大小。
推荐阅读
- push-notification - IBM MFP 8 推送通知休息 API 示例
- java - 刷新 DataOutputStream 后 DataInputStream 未接收到数据
- javascript - 我们如何使用 jquery 更改 tr 的背景颜色?
- c# - 在c#中显示日期选择器的日期对话框
- c# - 删除gridviewlinkedbutton
- python - java.sql.BatchUpdateException: [Teradata JDBC Driver] [TeraJDBC 14.10.00.44] [Error 1338] [SQLState HY000] 用于 python etl 代码
- curl - Lua cURL如何获得json响应?
- python - 从 pdffonts 的命令输出中仅获取第三和第六列
- javascript - 从后面的代码中分配 Dropdownlist 选定值会引发错误
- git - 获取当前提交的新标签,而不获取更新的提交