代码之家  ›  专栏  ›  技术社区  ›  Maciej Goszczycki

包含具有特征参数的结构的框的大小

  •  2
  • Maciej Goszczycki  · 技术社区  · 7 年前

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

    trait Foo {}
    
    struct Bar<T: Foo> {
        bars: Vec<Box<Bar<dyn Foo>>>,
        foo: T,
    }
    

    ?Sized 必然 T ,但我不明白为什么会这样。我想这是因为所有的特征对象都有相同的大小,但是 Bar 取决于混凝土类型的大小 . 如果是,情况如何 酒吧 用一个没有尺寸的 T 在记忆中表现出来?特别是在堆上跟踪其大小的内容,以及为什么不能在大小写的情况下使用此机制。

    1 回复  |  直到 7 年前
        1
  •  0
  •   Peter Hall    7 年前

    类型 dyn Foo 在编译时没有已知的大小。所以当你写作的时候 Bar<dyn Foo> ,编译器不允许这样做,因为(默认情况下)类型参数必须调整大小。编译器建议您通过允许 T T 成为 戴恩福

    怎么样 Bar 用一个没有尺寸的 在记忆中表现出来?

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

    目前没有此类对象的文档。它不完全是一个trait对象,但它是一个指针,指向一些可能没有大小的东西。正如您的示例所示,这是有效的。但我不能告诉你 vtable 指针被存储是因为我不知道,也不知道如何找到。

    每个对象的大小实际上并没有改变-只是每个实例可能不同。机制 可以 Sized 但你没有一个大箱子!即使是为了 T 那是大小的 bars 收集将包含箱 酒吧<dyn Foo> 没有尺寸。所以你需要 T: ?Sized (相对于 T: !Sized ),表示这种类型的 T 有大小或没有大小。

    推荐文章