gpt4 book ai didi

vector - 如何将向量复制到另一个位置并重用现有的分配内存?

转载 作者:行者123 更新时间:2023-12-03 11:23:44 25 4
gpt4 key购买 nike

在 C++ 中,要将向量的内容复制到另一个向量,我们使用赋值运算符 dest = src .但是,在 Rust 中 src将移入 dest并且不再可用。

我知道最简单的答案是做 dest = src.clone() (为了这个问题,我们假设 T 中的 Vec<T>Clone )。但是 - 如果我理解正确的话 - 这会创建一个全新的第三向量,其中复制的内容为 src并将其移动到 dest ,扔掉dest的动态分配数组。如果这是正确的,当我们可以将内容直接复制到 dest 时,这是完全不必要的动态分配。 (假设它有足够的容量)。

下面是我制作的一个函数,它完全符合我的意愿:清空 dest向量并复制 src 的元素到它。

// copy contents of src to dest without just cloning src
fn copy_content<T: Clone>(dest: &mut Vec<T>, src: &Vec<T>) {
dest.clear();
if dest.capacity() < src.len() {
dest.reserve(src.len());
}
for x in src {
dest.push(x.clone());
}
}

有没有办法使用内置或标准库实用程序来做到这一点?是 dest = src.clone()由编译器优化以执行此操作?

我知道如果 T具有动态资源,然后来自 src.clone() 的额外分配没什么大不了的,但如果 T是例如 i32或任何其他 Copy type 然后它会强制分配,而无需分配。

最佳答案

你有没有看过definition of Clone ?它有众所周知的clone方法也是一种有用但经常被遗忘的方法 clone_from method :

pub trait Clone : Sized {
fn clone(&self) -> Self;
fn clone_from(&mut self, source: &Self) {
*self = source.clone()
}
}
引用文档:

Performs copy-assignment from source.

a.clone_from(&b) is equivalent to a = b.clone() in functionality, but can be overridden to reuse the resources of a to avoid unnecessary allocations.


当然 a type such as Vec does not use the provided-by-default clone_from and defines以更有效的方式使用它自己,类似于您在 C++ 中通过编写 dest = src 获得的内容:
fn clone_from(&mut self, other: &Vec<T>) {
other.as_slice().clone_into(self);
}
[T]::clone_into being defined as :
fn clone_into(&self, target: &mut Vec<T>) {
// drop anything in target that will not be overwritten
target.truncate(self.len());
let len = target.len();

// reuse the contained values' allocations/resources.
target.clone_from_slice(&self[..len]);

// target.len <= self.len due to the truncate above, so the
// slice here is always in-bounds.
target.extend_from_slice(&self[len..]);
}

关于vector - 如何将向量复制到另一个位置并重用现有的分配内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59604714/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com