snippetrustCritical
How do I create a Vec from a range and shuffle it?
Viewed 0 times
howfromandshufflevecrangecreate
Problem
I have the following code:
and get the following error:
I think I understand that the content of vectors and slices is immutable and that causes the error here, but I'm unsure.
The signature of
I know that there must be an easy fix, but I tried my best and couldn't get it to work.
extern crate rand;
use rand::{thread_rng, Rng};
fn main() {
let mut vec: Vec = (0..10).collect();
let mut slice: &[u32] = vec.as_mut_slice();
thread_rng().shuffle(slice);
}and get the following error:
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]
I think I understand that the content of vectors and slices is immutable and that causes the error here, but I'm unsure.
The signature of
as_mut_slice is pub fn as_mut_slice(&'a mut self) -> &'a mut [T], so the slice should be mutable, but it somehow isn't.I know that there must be an easy fix, but I tried my best and couldn't get it to work.
Solution
Rand v0.6.0
The
See it on Playground.
Original answer
You're very close. This should work:
In fact, you don't need an annotation on
You don't even need the intermediate variable:
You should read The Rust Programming Language as it explains the concepts of ownership and borrowing and how they interact with mutability.
The
Rng::shuffle method is now deprecated; rand::seq::SliceRandom trait should be used. It provides the shuffle() method on all slices, which accepts an Rng instance:// Rust edition 2018 no longer needs extern crate
use rand::thread_rng;
use rand::seq::SliceRandom;
fn main() {
let mut vec: Vec = (0..10).collect();
vec.shuffle(&mut thread_rng());
println!("{:?}", vec);
}See it on Playground.
Original answer
You're very close. This should work:
extern crate rand;
use rand::{thread_rng, Rng};
fn main() {
let mut vec: Vec = (0..10).collect();
let slice: &mut [u32] = &mut vec;
thread_rng().shuffle(slice);
}&mut [T] is implicitly coercible to &[T], and you annotated the slice variable with &[u32], so the slice became immutable: &mut [u32] was coerced to &[u32]. mut on the variable is not relevant here because slices are just borrows into data owned by someone else, so they do not have inherited mutability - their mutability is encoded in their types.In fact, you don't need an annotation on
slice at all. This works as well:extern crate rand;
use rand::{thread_rng, Rng};
fn main() {
let mut vec: Vec = (0..10).collect();
let slice = vec.as_mut_slice();
thread_rng().shuffle(slice);
}You don't even need the intermediate variable:
extern crate rand;
use rand::{thread_rng, Rng};
fn main() {
let mut vec: Vec = (0..10).collect();
thread_rng().shuffle(&mut vec);
}You should read The Rust Programming Language as it explains the concepts of ownership and borrowing and how they interact with mutability.
Code Snippets
// 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);
}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);
}Context
Stack Overflow Q#26033976, score: 133
Revisions (0)
No revisions yet.