55

我有以下代码:

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

我知道必须有一个简单的解决方法,但我尽了最大努力,却无法让它发挥作用。

4

2 回答 2

83

兰德 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);
}

在操场上看到它。

原始答案

你很亲密。这应该有效:

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]被强制转换为&[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);
}

您应该阅读Rust 编程语言,因为它解释了所有权和借用的概念以及它们如何与可变性交互。


于 2014-09-25T09:46:36.420 回答
16

你可以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);
}
于 2015-12-29T16:49:11.547 回答