如何将向量复制到另一个位置并重用现有分配的内存? [英] How can I copy a vector to another location and reuse the existing allocated memory?

查看:198
本文介绍了如何将向量复制到另一个位置并重用现有分配的内存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In C++, to copy the contents of a vector to another vector we use the assignment operator dest = src. However, in Rust src would be moved into dest and no longer usable.

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

I know the simplest answer is to do dest = src.clone() (for the sake of this question we'll assume T in Vec<T> is Clone). However - if I'm understanding correctly - this creates a brand new third vector with the copied contents of src and moves it into dest, throwing away dest's dynamically allocated array. If this is correct, it's a completely unnecessary dynamic allocation when we could have just copied the content directly into dest (assuming it had sufficient capacity).

下面是我制作的功能,完全符合我的意愿:清空 dest 向量并复制 src

Below is a function I've made that does exactly what I would like to do: empty out the dest vector and copy the elements of src to it.

// 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()来执行此操作?

Is there a way to do this with builtin or standard library utilities? Is the dest = src.clone() optimized by the compiler to do this anyway?

我知道如果 T 具有动态资源,则 src.clone()的额外分配并不重要,但是如果 T 例如 i32 或任何其他 Copy 类型,然后在不需要的情况下强制进行分配。

I know that if T has dynamic resources then the extra allocation from src.clone() isn't a big deal, but if T is e.g. i32 or any other Copy type then it forces an allocation where none are necessary.

推荐答案

您曾经看过 克隆 的定义?它具有众所周知的 clone 方法,但是它是一个有用但经常被忘记的 clone_from 方法

Did you ever look at the 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)等效于 a = b.clone(),但可以重写以重用 a 的资源,以避免不必要的分配。

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.

当然诸如 Vec 不使用默认提供的 clone_from 并以更有效的方式定义通过编写 dest = src

Of course a type such as Vec does not use the provided-by-default clone_from and defines its own in a more efficient way, similar to what you would get in C++ from writing dest = src:

fn clone_from(&mut self, other: &Vec<T>) {
    other.as_slice().clone_into(self);
}

[T] :: clone_into 被定义为

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..]);
}

这篇关于如何将向量复制到另一个位置并重用现有分配的内存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆