在参数化函数中复制/克隆向量的惯用 Rust 方法是什么? [英] What is the idiomatic Rust way to copy/clone a vector in a parameterized function?

查看:52
本文介绍了在参数化函数中复制/克隆向量的惯用 Rust 方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个参数化函数,该函数接受一个不可变向量、克隆或复制它、对新向量执行某些操作(例如对其进行洗牌)并将其作为新拥有的向量返回.如何做到这一点,最惯用的方法是什么?

尝试 #1

pub fn shuffle(vec: &mut [T]) {//... 内容已删除:将向量原地打乱//... 所以需要一个可变向量}pub fn shuffle_create_new(vec: &[T]) ->Vec T{让 mut newvec = vec.clone();洗牌(&mut newvec);返回 newvec.to_owned();}

失败:

error[E0596]: 不能将不可变的借来内容作为可变借用-->src/main.rs:8:13|8 |洗牌(&mut newvec);|^^^^^^^^^^^^ 不能借为可变

即使我将 newvec 声明为可变的.我不明白为什么.

尝试 #2

pub fn shuffle_owned(mut vec: Vec) ->Vec T{shuffle(&mut vec);返回 vec;}

虽然编译,但它不做我想要的.您传递给 shuffle_owned 的向量被移动到函数中,进行混洗,然后将其所有权转移回调用者(通过返回值).所以原始向量被修改.

我想知道如何传入一个不会突变的向量,但是将值克隆到一个新的盒装向量中并在完成时返回——就像你在函数式编程语言中所做的那样具有不可变数据(例如 Clojure).

解决方案

您的尝试 #1 几乎是正确的,您只需要将 to_owned() 移到第一行:

fn shuffle(vec: &mut [T]) {//...}fn shuffle_create_new(vec: &[T]) ->Vec T{让 mut newvec = vec.to_vec();洗牌(&mut newvec);新维克}

发生这种情况是因为在切片上调用 clone() 将返回一个切片(即 &[T]),并且您不能从 &[T]&mut [T] 因为你不能选择引用的可变性(借用的指针).但是,当您调用 to_owned() 时,您将获得 Vec 的新实例,您可以将其放入可变变量中以获得可变向量.>

从 Rust 1.0 开始,slice::to_vecToOwned trait 中的 to_owned() 方法可用于从 &[T]Vec代码>.

现在还有几种方法可以从 Vec 获取 &mut [T]:切片符号(&mut vec[..])、deref 转换(&mut *vec)或直接方法调用(vec.as_mut_slice(),虽然这个方法已被弃用):

I'm trying to write a parameterized function that takes an immutable vector, clones or copies it, does something to the new vector (such as shuffle it) and returns it as a new owned vector. How can this be done and what is the most idiomatic way to do it?

Attempt #1

pub fn shuffle<T>(vec: &mut [T]) {
    // ... contents removed: it shuffles the vector in place
    // ... so needs a mutable vector
}

pub fn shuffle_create_new<T: Clone>(vec: &[T]) -> Vec<T> {
    let mut newvec = vec.clone();
    shuffle(&mut newvec);
    return newvec.to_owned();
}

Fails with:

error[E0596]: cannot borrow immutable borrowed content as mutable
 --> src/main.rs:8:13
  |
8 |     shuffle(&mut newvec);
  |             ^^^^^^^^^^^ cannot borrow as mutable

even though I declared newvec as mutable. I don't understand why.

Attempt #2

pub fn shuffle_owned<T: Clone>(mut vec: Vec<T>) -> Vec<T> {
    shuffle(&mut vec);
    return vec;
}

While this compiles, it doesn't do what I want. The vector you pass into shuffle_owned gets moved into the function, shuffled and then has its ownership transferred back to the caller (via the return value). So the original vector is modified.

I want to know how to pass in a vector that will not be mutated, but have the values cloned into a new boxed vector and returned when finished - as you do in a functional programming language that has immutable data (such as Clojure).

解决方案

Your attempt #1 is almost correct, you just have to move to_owned() to the first line:

fn shuffle<T>(vec: &mut [T]) {
    // ...
}

fn shuffle_create_new<T: Clone>(vec: &[T]) -> Vec<T> {
    let mut newvec = vec.to_vec();
    shuffle(&mut newvec);
    newvec
}

This happens because calling clone() on a slice will return you a slice (i.e. &[T]), and you cannot go from &[T] to &mut [T] because you cannot choose mutability of a reference (borrowed pointer). When you call to_owned(), however, you are getting a fresh instance of Vec<T> and you can put it into a mutable variable to get mutable vector.

As of Rust 1.0, either slice::to_vec or to_owned() method from the ToOwned trait can be used to create Vec<T> from &[T].

There are also now several ways to obtain &mut [T] from Vec<T>: the slicing notation (&mut vec[..]), the deref conversion (&mut *vec) or the direct method call (vec.as_mut_slice(), though this one is deprecated):

这篇关于在参数化函数中复制/克隆向量的惯用 Rust 方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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