Compiler errors 包含带有特征参数的结构的框的大小

Compiler errors 包含带有特征参数的结构的框的大小,compiler-errors,rust,traits,typechecking,Compiler Errors,Rust,Traits,Typechecking,我需要一个包含trait对象和更多自身的结构。令人失望的是,以下代码未编译: trait Foo {} struct Bar<T: Foo> { bars: Vec<Box<Bar<dyn Foo>>>, foo: T, } trait Foo{} 结构条{ 酒吧:Vec, 傅:T, } 我通过添加绑定到T的大小的来强制编译,但我不明白为什么会出现这种情况。我假设这是因为所有trait对象都具有相同的大小,但是条的大小取决于具

我需要一个包含trait对象和更多自身的结构。令人失望的是,以下代码未编译:

trait Foo {}

struct Bar<T: Foo> {
    bars: Vec<Box<Bar<dyn Foo>>>,
    foo: T,
}
trait Foo{}
结构条{
酒吧:Vec,
傅:T,
}

我通过添加绑定到
T
大小的
来强制编译,但我不明白为什么会出现这种情况。我假设这是因为所有trait对象都具有相同的大小,但是
条的大小取决于具体类型
T
的大小。如果是这样,那么在内存中如何表示带有未指定大小的
T
Bar
?具体来说,是什么在堆上跟踪它的大小,以及为什么不能在大小的情况下使用此机制。

类型
dyn Foo
在编译时没有已知的大小。因此,当您编写
Bar
时,编译器将不允许这样做,因为(默认情况下)类型参数必须调整大小。编译器建议您通过允许
T
不调整大小来解决此问题,这是
T
变为
dyn Foo
所必需的

在内存中如何表示带有未调整大小的
T
Bar

一个结构最多允许有一个未调整大小的字段。然后,它的数据在内存中首先显示大小字段,最后显示未大小字段。这个限制意味着在编译时可以知道所有字段的相对内存地址。带有
?size
类型参数的结构本身可以调整大小,也可以不调整大小,具体取决于其参数的具体类型。当结构没有大小时,它不能进入堆栈,因此只能从指针后面使用它

目前没有此类对象的文档。它不完全是一个trait对象,但它是指向某个可能无法确定大小的对象的指针。正如您的示例所示,这是有效的。但是我不能告诉您
vtable
指针存储在哪里,因为我不知道,也不知道如何找到

具体来说,是什么在堆上跟踪其大小,以及为什么不能在大小相同的情况下使用此机制


每个对象的大小实际上并没有改变——只是每个实例的大小可能有所不同。该机制可以“在
大小的
案例中”使用,但您没有大小的案例!即使对于已调整大小的
T
Bar
集合也将包含未调整大小的
Bar
框。这就是为什么你需要
T:?Sized
(与
T:!Sized
)来表示这种类型适用于
T
的大小或非大小。

在我看来,你可能想要
Bar
es的
Box
es的
Bar
s。切换这些应该可以解决问题。我已经考虑过这种方法,但是
Box
没有实现
Foo
。实际上,
Foo
是一个更大的特性,为一个
Box
实现一切都将是一件苦差事。一种选择是将u T/
的边界切换为:new
AsRef
,它可以工作,但不太整洁。但是
Box
不能实现
Foo
-。事实上
Foo
是一个相当大的特性,实现它不仅是一件苦差事,不过,这不太可能是您真正想要的,因为结构中有一个T字段,它的大小必须是我最初的想法,但让我惊讶的是,它似乎工作得很好?!我假设在实践中,如果T是一个未大小化的类型,即使绑定了
?size
,编译器也会失败。示例。如果您尝试在那里实际使用未大小的类型,您将得到一个错误。这很好,因为我实际上不想传递任何未大小的类型。虽然我仍然不明白为什么添加
?大小
对于
的工作是必要的。@mgoszcz2这是因为类型
dyn Foo
不是
size
。这让我回到原来的问题。什么跟踪盒装
条的物理堆大小?只是所有的trait对象,仅仅是vtable,都有相同的大小吗?