【问题标题】:Why is `dyn Trait` not Sized? [duplicate]为什么`dyn Trait`没有大小? [复制]
【发布时间】:2021-10-14 15:15:51
【问题描述】:

在关于不同类型内存布局的 Rust tutorial 中,它谈到了 trait 对象。然而,如图所示,存在于堆栈中的特征对象部分具有恒定大小:一个 word 用于指向值的指针,另一个 word 用于指向其 vtable 的指针 = 64 位机器上的 16 字节.

我的问题是,如果特征对象具有固定大小,为什么我们需要对它的引用?这个由两个词组成的“胖指针”实际上是引用吗,因为这与引用在所有其他 Rust 中的工作方式不一致,它只是指向某些数据的瘦指针。而且我不相信 Rust 会不必要地隐藏这些细节并且前后不一致。

【问题讨论】:

  • &dyn Trait 是胖指针(2 个字)。 dyn Trait(没有参考)没有大小。是的,Rust 是“不一致的”,因为普通指针和胖指针都使用&。另请参阅 &[u8] 的大小与 &[u8; N] 的大小。
  • 该图像不构成完整示例。 w 是一个可变引用,类型为&mut dyn Write,实际上是Sized。不是Sized 的是底层值,它的类型在被制成特征对象时被擦除。
  • dyn Trait 指的是数据指针后面的实际对象,可以是任意大小。 (在这种情况下,它是 3 个机器字,因为实现者是 Vec。)当你把它放在一个引用后面时,你会得到一个熟悉的具有常量大小的对象,一个指针-指针对(如果是 trait 对象)或一个指针切片情况下的 -length 对。

标签: rust reference trait-objects


【解决方案1】:

正如我在 cmets 中了解到的,Rust 实际上在处理 & 的方式上不一致,这取决于上下文。例如,&dyn Trait&[T] 是胖指针,但一般来说,&T 将是瘦指针。

【讨论】:

  • 我不同意这个答案。瘦指针和胖指针的大小不同,但在编译时就知道使用了哪一个。而&dyn Trait 的大小总是两个字。问题是dyn Trait 是一种虚拟类型。它在内存中没有布局,因为它位于内存中的两个不同位置(vtable 和数据)。但是&dyn Trait被定义为两个指向这两个不同内存位置的指针。
  • @OzgurMurat 这正是我所说的。我的评论意味着 Rust 中的 '&' 与 C/C++ 中的不同,它只是 addressof 运算符。在这里,单独的'&'并不意味着什么,它所应用的内容也需要知道。来自 C++,我误以为它必须是一个词长,但 obv 动态调度需要两个词,因此我感到困惑。
  • 我的意思是,您需要引用特征对象的原因与其他 DST 需要引用的原因不同。特征对象没有大小,因为没有特征对象。它们只是概念性的东西。只有 Trait 对象指针存在,它不是一个指针而是两个指向不同内存区域的指针(因此我们不能谈论一个对象)。
  • @OzgurMurat 是的,正是对 trait 对象的引用与对传统结构/数据的引用具有不同的语义含义,但使用相同的语法却让我感到困惑。感谢您用比我更好的语言表达它:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-02
相关资源
最近更新 更多