我有一个简单的问题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(使用前将#替换为@)