2017-10-06 6 views
4

J'essaie de passer une section mutable à une fonction et de l'utiliser dans plusieurs boucles à l'intérieur.Déplacez l'erreur dans la boucle for lorsque vous ne réalisez pas une tranche mutable

function1 produit une erreur. Passer à function2 ou function3 fait disparaître les erreurs, mais je ne comprends pas les différences entre function1 et function2. v et &mut *v me semblent similaires.

Pourquoi le function1 ne fonctionne-t-il pas alors que les autres le font?

fn main() { 
    let mut v = Vec::new(); 

    function1(&mut v); 
    function2(&mut v); 
    function3(&mut v); 
} 

// Move Error 
fn function1(v: &mut [i32]) { 
    for l in v {} 
    for l in v {} // <-- Error Here !!! 
} 

// Works Fine 
fn function2(v: &mut [i32]) { 
    for l in &mut *v {} 
    for l in &mut *v {} 
} 

// Works Fine 
fn function3(v: &mut [i32]) { 
    for l in v.iter_mut() {} 
    for l in v.iter_mut() {} 
} 

L'erreur:

error[E0382]: use of moved value: `v` 
    --> src/main.rs:12:14 
    | 
11 |  for l in v {} 
    |    - value moved here 
12 |  for l in v {} // <-- Error Here !!! 
    |   ^value used here after move 
    | 
    = note: move occurs because `v` has type `&mut [i32]`, which does not implement the `Copy` trait 
+1

Salut! Votre message comportait deux questions mineures: 1. votre exemple n'était pas minimal et 2. vous avez posé deux questions différentes. J'ai essayé de résoudre les deux problèmes en éditant votre post pour éviter que vous soyez downvoted (votre vraie question est vraiment bonne). Si vous pensez que j'ai trop changé ou que vous n'êtes pas d'accord avec l'édition pour une autre raison, il vous suffit de la reculer! –

Répondre

3

&mut *v fait un soi-disant "réemprunter". Cela signifie qu'au lieu d'itérer sur la référence d'origine, vous itérez sur une nouvelle référence.

Pensez-y de cette façon:


Si vous avez un appartenant vecteur, et vous itérer dessus, vous obtenez la même erreur si vous essayez itérer encore, parce qu'il a été déplacé dans la boucle for.

Si à la place vous empruntez le vecteur et parcourez l'emprunt, vous pouvez le faire autant de fois que vous le souhaitez.


Si vous avez ralonge mutable, et vous itérer dessus, vous déplacez le dans la mutable emprunter boucle. Donc c'est parti maintenant.

Si à la place vous créez une nouvelle référence pointant vers l'emprunt mutable, vous quittez simplement la nouvelle référence. Une fois l'itération terminée, le nouvel emprunt mutable est parti, ce qui signifie que l'emprunt mutable original peut être consulté à nouveau.

+1

Aussi. 'pour i in v {...}' desugars pour 'let mut iter = v.into_iter(); alors que Some (i) = iter.next {...} '. 'into_iter' consomme' v', '(& mut * v) .into_iter()' consomme une référence fraîchement créée. – red75prime