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

时间:2014-01-26 22:03:59

标签: rust

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

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

失败:

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

即使我宣称newvec是可变的。我不明白为什么。

尝试#2

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

虽然这个编译,但它没有做我想要的。传递到shuffle_owned的向量会将移动到函数中,进行随机播放,然后将其所有权转移回调用方(通过返回值)。所以原始矢量是修改

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

2 个答案:

答案 0 :(得分:20)

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

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
}

这是因为在切片上调用clone()会返回一个切片(即&[T]),并且您无法从&[T]转到&mut [T],因为您无法选择可变性引用(借用指针)。但是,当您调用to_owned()时,您将获得Vec<T>的新实例,并且可以将其放入可变变量中以获取可变向量。

从Rust 1.0开始,ToOwned特征中的slice::to_vecto_owned()方法可用于从Vec<T>创建&[T]

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

答案 1 :(得分:7)

这可能是你想要的:

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

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