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

How can I copy a vector to another location and reuse the existing allocated memory?

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

我知道最简单的答案是 dest = src.clone()(为了这个问题,我们假设 Vec<T> 中的 TClone)。但是 - 如果我理解正确的话 - 这会创建一个全新的第三个向量,其中包含 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 类型,然后它会在需要 none 的地方强制分配。

你有没有看过 definition of Clone? It has the well known clone method but also a useful but often forgotten 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..]);
}