iterator - 如何从一个范围创建一个 Vec 并对其进行洗牌?

标签 iterator immutability rust mutability

我有以下代码:

extern crate rand;

use rand::{thread_rng, Rng};

fn main() {
    let mut vec: Vec<u32> = (0..10).collect();
    let mut slice: &[u32] = vec.as_mut_slice();

    thread_rng().shuffle(slice);
}

并得到以下错误:

error[E0308]: mismatched types
 --> src/main.rs:9:26
  |
9 |     thread_rng().shuffle(slice);
  |                          ^^^^^ types differ in mutability
  |
  = note: expected type `&mut [_]`
             found type `&[u32]`

我想我明白向量和切片的内容是不可变的,这会导致此处出现错误,但我不确定。

as_mut_slice的签名是pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] ,所以切片应该是可变的,但不知何故不是。

我知道一定有一个简单的修复方法,但我已尽力而为,但还是没能成功。

最佳答案

兰德 v0.6.0

Rng::shuffle 方法现已弃用;应使用 rand::seq::SliceRandom 特性。它在所有切片上提供了 shuffle() 方法,它接受一个 Rng 实例:

// Rust edition 2018 no longer needs extern crate

use rand::thread_rng;
use rand::seq::SliceRandom;

fn main() {
    let mut vec: Vec<u32> = (0..10).collect();
    vec.shuffle(&mut thread_rng());
    println!("{:?}", vec);
}

查看on Playground .

原始答案

你非常接近。这应该有效:

extern crate rand;

use rand::{thread_rng, Rng};

fn main() {
    let mut vec: Vec<u32> = (0..10).collect();
    let slice: &mut [u32] = &mut vec;

    thread_rng().shuffle(slice);
}

&mut [T] 可隐式强制转换为 &[T],并且您使用 &[u32 注释了 slice 变量],因此切片变得不可变:&mut [u32] 被强制转换为 &[u32]。变量上的 mut 在这里不相关,因为切片只是借用到其他人拥有的数据中,所以它们没有继承的可变性 - 它们的可变性被编码在它们的类型中。

事实上,您根本不需要在 slice 上添加注释。这也适用:

extern crate rand;

use rand::{thread_rng, Rng};

fn main() {
    let mut vec: Vec<u32> = (0..10).collect();
    let slice = vec.as_mut_slice();

    thread_rng().shuffle(slice);
}

你甚至不需要中间变量:

extern crate rand;

use rand::{thread_rng, Rng};

fn main() {
    let mut vec: Vec<u32> = (0..10).collect();
    thread_rng().shuffle(&mut vec);
}

你应该阅读 The Rust Programming Language因为它解释了所有权和借用的概念以及它们如何与可变性相互作用。


关于iterator - 如何从一个范围创建一个 Vec 并对其进行洗牌?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26033976/

相关文章:

Python 迭代 - 查找字符串中数字的乘积的问题

java - 对于 ArrayList 使用 Iterator 代替 ListIterator 有什么好处?

c++ - C++ 容器的迭代器失效规则

c#-4.0 - 为什么当引用更改时,可变 StringBuilder 的行为类似于不可变字符串?

java - 为什么首选使用不可变对象(immutable对象)作为 Set 的元素?

rust - 当我尝试提交表单Rocket Rust时给出错误422

rust - 如何在测试中运行并发任务? [复制]

C++ vector 迭代器 : erase() last item crash

http - 如何同时使用 Rejection 和问号运算符来处理 Warp 中的错误?

string - Swift "mutable"字符串真的是可变的,还是它们就像 Java 字符串一样?