web-dev-qa-db-fra.com

Comment créer un Vec à partir d'une plage et le mélanger?

J'ai le code suivant:

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

et obtenez l'erreur suivante:

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]`

Je pense que je comprends que le contenu des vecteurs et des tranches est immuable et cela provoque l'erreur ici, mais je ne suis pas sûr.

La signature de as_mut_slice Est pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T], donc la tranche doit être modifiable, mais ce n'est pas le cas.

Je sais qu'il doit y avoir une solution facile, mais j'ai fait de mon mieux et je n'ai pas réussi à le faire fonctionner.

29
le_me

Tu es très proche. Cela devrait fonctionner:

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] Est implicitement contraint à &[T], Et vous avez annoté la variable slice avec &[u32], De sorte que la tranche est devenue immuable: &mut [u32] A été contraint à &[u32]. mut sur la variable n'est pas pertinent ici car les tranches sont simplement des emprunts dans des données appartenant à quelqu'un d'autre, donc elles n'ont pas de mutabilité héritée - leur mutabilité est encodée dans leurs types.

En fait, vous n'avez absolument pas besoin d'annotation sur slice. Cela fonctionne également:

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

Vous n'avez même pas besoin de la variable intermédiaire:

extern crate Rand;

use Rand::{thread_rng, Rng};

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

Vous devriez lire Le Rust langage de programmation car il explique les concepts de propriété et d'emprunt et comment ils interagissent avec la mutabilité.


Mise à jour: depuis Rand v0.6.0, la méthode Rng::shuffle Est désormais obsolète. À la place, la caractéristique Rand::seq::SliceRandom Doit être utilisée. Il fournit la méthode shuffle() sur toutes les tranches, qui accepte une instance 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);
}

Voir sur Playground .

32
Vladimir Matveev

Vous pouvez utiliser shuffle comme ceci:

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);
}
15
Akavall