Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 在参数化函数中复制/克隆向量的惯用方法是什么?_Rust - Fatal编程技术网

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

Rust 在参数化函数中复制/克隆向量的惯用方法是什么?,rust,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

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

尝试#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();
}
即使我声明
newvec
是可变的。我不明白为什么

尝试#2

pub fn shuffle_owned<T: Clone>(mut vec: Vec<T>) -> Vec<T> {
    shuffle(&mut vec);
    return vec;
}
pub fn shuffle_owned(mut-vec:vec)->vec{
洗牌(&mut-vec);
返回向量;
}
虽然这可以编译,但它并不能满足我的需要。传递到
shuffle\u owned
中的向量将移动到函数中,进行洗牌,然后将其所有权转移回调用方(通过返回值)。所以原始向量被修改了

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

您的尝试#1几乎是正确的,您只需将
移动到_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
}
fn shuffle(vec:&mut[T]){
// ...
}
fn shuffle_create_new(vec:&[T])->vec{
让mut newvec=vec.to_vec();
洗牌(&mut-newvec);
纽维克
}
这是因为在片上调用
clone()
将返回一个片(即
&[T]
),并且您无法从
&[T]
转到
&mut[T]
,因为您无法选择引用的可变性(借用指针)。然而,当您调用
到_owned()
时,您会得到一个新的
Vec
实例,您可以将其放入可变变量中以获得可变向量

从Rust 1.0开始,可以使用
ToOwned
特性中的或方法从
和[T]
创建
Vec


现在还有几种方法可以从
Vec
获取
&mut[T]
:切片表示法(
&mut-Vec[…]
)、deref转换(
&mut*Vec
)或直接方法调用(
Vec.as_mut_-slice()
),尽管不推荐使用这种方法):

这可能是您想要的:

pub fn copy_shuffle<T: Clone>(vec: &Vec<T>) -> Vec<T> {
    let mut vec = vec.clone();
    shuffle(&mut vec);
    vec
}
pub fn copy\u shuffle(vec:&vec)->vec{
让mut-vec=vec.clone();
洗牌(&mut-vec);
vec
}

pub fn copy_shuffle(vec:&T])->vec{
设mut-vec=vec.to_-vec();
洗牌(&mut-vec);
vec
}

to _owned
克隆
[T]
的每个元素,因此需要
T
来实现克隆(
)是的,这解释了错误。谢谢。我已经更新了我的答案,因为你的建议修复了第一个错误,但我仍然没有弄清楚如何实现我的总体目标。你是对的,这也很有效-谢谢你关于这种构造的提示!您的答案与@Vladimir的答案之间的区别在于,当您调用它时,您必须使用地址:
copy\u shuffle(&myvec)
vs.
shuffle\u create\u new(myvec)
。我猜弗拉基米尔的版本更地道,但我不是很确定。我会接受他的回答,但让社区告诉我,如果我的投票数错了。@quux00,你是对的。在
&[T]
的情况下,您有两个级别的间接寻址(我不确定,也许LLVM可以在执行代码时对其进行优化,但它们在语义级别上仍然存在),而
&[T]
~[T]
只有一个。然而,有时这是唯一可行的方法,例如,在实现像
Add
这样的泛型特征时,至少在将未大小的类型(比如
[T]
)添加到语言中之前是如此。根据方法
vec,as_mut_slice()
并没有被弃用。
pub fn copy_shuffle<T: Clone>(vec: &[T]) -> Vec<T> {
    let mut vec = vec.to_vec();
    shuffle(&mut vec);
    vec
}