error[E0382]: borrow of moved value: `folder_2`
--> src/main.rs:32:5
|
29 | let mut folder_2 = Folder::new();
| ------------ move occurs because `folder_2` has type `Folder`, which does not implement the `Copy` trait
30 |
31 | folder_1.add_folder(Box::new(folder_2));
| -------- value moved here
32 | folder_2.add_file(String::from("b.txt")); // Error
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ value borrowed here after move
Question
Is there a correct way to do this in Rust or is it only possible through unsafe means? Any suggestions and tips would be appreciated.
Depends on what exactly you want to achieve. Almost the whole point of Rust is to ensure that you can not have subfolder accessible simultaneously via folder which owns it and via some other variable.
After you did folder_1.add_folder you have made folder_2 impossible to use.
Of course it's still possible to access it via folder_1:
folder_1.sub_folder[0].add_file(String::from("b.txt")); // Works
You can also borrow it and use it this way:
let folder_2 = &mut folder_1.sub_folder[0];
folder_2.add_file(String::from("b.txt")); // Works
But you can never have two valid names for the same mutable object (except via interior mutability) — and, as I have already said, that that's the whole point!
You are still trying to invent some magic way of making sure that you can have shared access via two different variables without any trace of said shared access in the code where you use these.
Given the fact that Rust is made to ensure that's not possible… no wonder you are having trouble.
Your previous version was always correct, just you haven't done everything explicit.
fn main() {
let mut folder_1 = Folder::new();
let mut folder_2 = Rc::new(RefCell::new(Folder::new()));
folder_1.add_folder(folder_2.clone());
folder_2.borrow_mut().add_file(String::from("b.txt")); // Works
}
Note that you still have to explicitly create two references with clone and then “activate” one of these shared references with borrow_mut… that way you can see that you are creating sharing on purpose and then you can also see where you are switching from “shared access” mode to “mutation” mode.