要使用旧向量(我想清空)的内容创建一个新向量,我将使用:
foo.bar = my_vector.drain(0..).collect();
这是惯用的 Rust 吗?
Drain() 是否已优化掉,原始向量的内存是否已分配给新向量?
或者每个元素都被一一复制到新的堆分配中?
要使用旧向量(我想清空)的内容创建一个新向量,我将使用:
foo.bar = my_vector.drain(0..).collect();
这是惯用的 Rust 吗?
Drain() 是否已优化掉,原始向量的内存是否已分配给新向量?
或者每个元素都被一一复制到新的堆分配中?
我会做
这是一个更通用的解决方案。
std::mem::take()
改变其参数以窃取其内容并将其保留为默认状态。被盗内容用于创建相同类型的新值。实际的窃取
Vec
操作是结构本身的简单字节交换(a 、aString
、任何其他容器的一些指针/整数...)。存储的元素(可能是堆分配的)保留在原处,因此最终此操作非常便宜(复制然后清除很少的字节,即sizeof
结构)。将所有元素从一个元素移动
Vec
到另一个元素的最便宜的方法是take
:这将赋予分配所有权和所有元素,
foo.bar
并保持my_vector
默认状态(空,没有分配空间)。您可以使用
.drain()
+.collect()
来移动元素,同时保留 的my_vector
分配,但是您可以通过使用上述方法来避免复制成本,然后简单地.reserve()
再次将空间放回去。如果
foo.bar
还分配了元素或空间,那么对它们来说可能更好swap
(交换它们的元素和分配),然后清除my_vector
(如果您希望它为空):这可以避免随后放入元素时的分配
my_vector
。我不认为编译器会看到这种优化,我也不完全确定它是否有效。您可以在编译器资源管理器上看到您的代码确实发出分配,后跟
memmove
:对于
drain
整个向量,我使用的drain(..)
显式数字越少越好,但更符合您的意图可能是或者