Pourquoi n1_mut
est-il toujours valide dans cet exemple? Il a été déplacé dans Option::Some
alors ne devrait-il pas être invalide?Pourquoi l'affectation à un membre d'un pointeur est-elle toujours valide après le déplacement du pointeur?
struct MyRecordRec2<'a> {
pub id: u32,
pub name: &'a str,
pub next: Box<Option<MyRecordRec2<'a>>>
}
#[test]
fn creating_circular_recursive_data_structure() {
let mut n1_mut = MyRecordRec2 {
id: 1,
name: "n1",
next: Box::new(None)
};
let n2 = MyRecordRec2 {
id: 2,
name: "n2",
next: Box::new(Some(n1_mut))
};
//Why is n1_mut still valid?
n1_mut.next = Box::new(Some(n2));
}
Ce qui suit ne compile pas avec le familier « l'utilisation de la valeur déplacée » Erreur:
#[test]
fn creating_and_freezing_circular_recursive_data_structure() {
let loop_entry = {
let mut n1_mut = MyRecordRec2 {
id: 1,
name: "n1",
next: Box::new(None),
};
let n2 = MyRecordRec2 {
id: 2,
name: "n2",
next: Box::new(Some(n1_mut)),
};
n1_mut.next = Box::new(Some(n2));
n1_mut
};
}
error[E0382]: use of moved value: `n1_mut`
--> src/main.rs:44:9
|
39 | next: Box::new(Some(n1_mut)),
| ------ value moved here
...
44 | n1_mut
| ^^^^^^ value used here after move
|
= note: move occurs because `n1_mut` has type `MyRecordRec2<'_>`, which does not implement the `Copy` trait
Intéressant. Je ne suis pas sûr que cela compte comme un bug - je ne pense pas que vous pouvez induire en erreur parce qu'il n'y a aucun moyen de lire la mémoire par la suite. Mais si vous gardez un pointeur brut sur la pile, vous pouvez dire que 'n1Mut.next' est bien défini: https://play.rust-lang.org/?gist=d41422bfd142c289667e7c2fb3183be0&version=undefined – trentcl
Il est intéressant de noter que ce n'est pas possible utilisez 'n1_mut.next' après. En outre, l'ajout d'une implémentation 'Drop' provoque:" error [E0383]: réinitialisation partielle de la structure non initialisée "n1_mut'" –