在参数化函数中复制/克隆向量的惯用 Rust 方法是什么?

我尝试编写一个参数化函数,它接受一个不可变的向量,克隆或复制它,对新的向量进行某些操作(如洗牌) ,并将其作为一个新的拥有向量返回。怎样才能做到这一点? 最常用的方法是什么?

第一次尝试

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();
}

失败的原因:

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

尽管我声明 newvec是可变的,我不明白为什么。

第二次尝试

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

在编译的过程中,它并没有按照我想要的方式运行。您传递给 shuffle_owned的向量将 感动转移到函数中,然后将其所有权转移回调用者(通过返回值)。原始矢量是 修改过的

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

109423 次浏览

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):

This is probably what you want:

pub fn copy_shuffle<T: Clone>(vec: &Vec<T>) -> Vec<T> {
let mut vec = vec.clone();
shuffle(&mut vec);
vec
}

or

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