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

le_*_*_me 25 iterator immutability mutability rust

我有以下代码:

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);
}
Run Code Online (Sandbox Code Playgroud)

并得到以下错误:

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]`
Run Code Online (Sandbox Code Playgroud)

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

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

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

Vla*_*eev 38

你很近.这应该工作:

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);
}
Run Code Online (Sandbox Code Playgroud)

&mut [T]是隐式强制的&[T],并且你用slice变量注释了变量&[u32],因此切片变得不可变:&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);
}
Run Code Online (Sandbox Code Playgroud)

你甚至不需要中间变量:

extern crate rand;

use rand::{thread_rng, Rng};

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

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


更新:自rand 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);
}
Run Code Online (Sandbox Code Playgroud)

在Playground上看到它.

  • @JL请参阅更新后的答案。 (3认同)

Aka*_*all 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);
}
Run Code Online (Sandbox Code Playgroud)

  • @JL,我明白了。谢谢。我尝试以另一种方式做到这一点:https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=74022e6f3a22741b98782ade77531691,但我收到不同的警告,不确定这是否是更好的解决方案。 (2认同)