如何从一个范围创建一个Vec并将其洗牌?

时间:2014-09-25 08:32:03

标签: 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],因此切片应该是可变的,但它不知道是不是。

我知道必须有一个简单的解决办法,但我尽我所能,无法让它发挥作用。

2 个答案:

答案 0 :(得分:28)

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

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]隐式强制,您使用slice注释&[u32]变量,因此切片变为不可变:&mut [u32]被强制转换为{ {1}}。关于变量的&[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);
}

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


更新:自rand v0.6.0起,extern crate rand; use rand::{thread_rng, Rng}; fn main() { let mut vec: Vec<u32> = (0..10).collect(); thread_rng().shuffle(&mut vec); } 方法现已弃用。相反,应该使用Rng::shuffle特征。它在所有切片上提供rand::seq::SliceRandom方法,该方法接受shuffle()实例:

Rng

on Playground

答案 1 :(得分:15)

您可以像这样使用shuffle

extern crate rand;

use rand::Rng;

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