Box 与 X 上的移动语义

2024-05-17

我有一个简单的问题Box<X>。 我明白它的作用,它分配X在堆上。 在 C++ 中,您使用new操作符在堆上分配一些东西,这样它就可以比当前作用域更长久(因为如果你在堆栈上创建一些东西,它就会在当前块的末尾消失)。

但阅读 Rust 的文档后,looks就像你可以在堆栈上创建一些东西,并且仍然利用语言的移动语义返回它,而不必求助于堆。 然后我不清楚什么时候使用Box<X>而不是简单地X.

我刚刚开始阅读有关 Rust 的内容,所以如果我遗漏了一些明显的内容,我深表歉意。


首先:C++11(及更新版本)也具有带有右值引用的移动语义。所以你的问题也适用于 C++。但请记住,与 Rust 不同,C++ 的移动语义非常不安全。

Second:“移动语义”一词在某种程度上暗示了“副本”的缺失,但事实并非如此。假设你有一个struct具有 100 个 64 位整数。如果您通过移动语义传输此结构的对象,那么这 100 个整数将被复制(当然,编译器的优化器通常可以删除这些副本,但无论如何......)。当处理处理堆上某种数据(或一般的指针)的对象时,移动语义的优势就会发挥出来。

例如,看看Vec(类似于C++的vector): 类型本身只包含一个指针和两个指针大小的整数 (ptr, len and cap)。当向量移动时,这 3 个 64 位仍然会被复制,但向量的主要数据(位于堆上)不会被触及。


话虽这么说,让我们讨论一下主要问题:“为什么要使用Box at all?”。其实有很多用例:

  • 无尺寸类型:某些类型(例如还包括闭包的特征对象)未确定大小,这意味着编译器不知道它们的大小。但是编译器必须知道每个堆栈帧的大小 - 因此那些未指定大小的类型不能存在于堆栈中。
  • 递归数据结构: 想一个BinaryTreeNode结构。它保存了两个名为“left”和“right”类型的成员...BinaryTreeNode?那是行不通的。因此,您可以将两个子级装箱,以便编译器知道结构的大小。
  • 巨大的结构:想想上面提到的 100 个整数结构。如果您不想每次都复制它,可以将其分配在堆上(这种情况很少发生)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Box 与 X 上的移动语义 的相关文章

随机推荐