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

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

失败于:

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

尽管我宣布newvec是可变的.我不明白为什么.

Attempt #2

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

虽然这可以编译,但它并不能满足我的要求.传入shuffle_owned的向量将moved放入函数中,经过洗牌,然后将其所有权转移回调用方(通过返回值).原来的向量是modified.

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

推荐答案

你的try #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],因为不能 Select 引用(borrow 指针)的可变性.然而,当你调用to_owned()时,你会得到一个Vec<T>的新实例,你可以把它放入一个可变变量中,得到可变向量.

在Rust 1.0中,ToOwned性状中的slice::to_vecto_owned()方法可以用于从&[T]性状中创建Vec<T>性状.

现在还有几种从Vec<T>中获取&mut [T]的方法:切片表示法(&mut vec[..])、deref转换(&mut *vec)或直接方法调用(vec.as_mut_slice(),尽管这一种已被弃用):

Rust相关问答推荐

通过解引用将值移出Box(以及它被脱糖到什么地方)?

默认特征实现中的生命周期问题

捕获FnMut闭包的时间不够长

rust 蚀生命周期 不匹配-不一定超过此处定义的生命周期

在Rust中克隆源自INTO_ITER()的迭代器的成本?

Rust从关联函数启动线程

如何获取光标下的像素 colored颜色 ?

Rust proc_macro 和 syn:解析空格

Rust 重写函数参数

为什么某些类型参数仅在特征边界中使用的代码在没有 PhantomData 的情况下进行编译?

可选包装枚举的反序列化

`use` 和 `crate` 关键字在 Rust 项目中效果不佳

Button.set_hexpand(false) 不会阻止按钮展开

闭包返回类型的生命周期规范

如何为整数切片定义一个带有额外函数的特性别名?

Rust中的标记特征是什么?

从 Rust 中的 if/else 中的引用创建 MappedRwLockWriteGuard

打印 `format_args!` 时borrow 时临时值丢失

将 `&T` 转换为新类型 `&N`

为什么我不能为 Display+Debug 的泛型类型实现 std::error::Error 但有一个不是泛型参数的类型?