A new comer, I'm trying to traverse a tree recursively to mutate some item fields without mutating the tree structure. The exec fn was expected with item, index, and the parent. Only the item fields need to be mutable.
So far what I've tried (some code was suggested by GitHub Copilot however):
fn main() {
// data structure
#[derive(Debug)]
enum Extra {
A(Bar),
B(Baz),
}
#[derive(Debug)]
struct Foo {
a: i32,
b: Extra,
}
#[derive(Debug)]
struct Bar {
c: i32,
d: i32,
}
#[derive(Debug)]
struct Baz {
children: Vec<Foo>,
}
// iterate function
fn iterate_foo(foo: &mut Foo, exec: fn(&mut Foo, usize, &Foo)) {
match &mut foo.b {
Extra::B(baz) => {
baz.children.iter_mut().enumerate().for_each(|(index, child)| {
exec(child, index, foo);
iterate_foo(child, exec)
});
},
_ => {},
}
}
// test
let mut foo_1 = Foo {
a: 1,
b: Extra::B(Baz {
children: vec![
Foo { a: 2, b: Extra::A(Bar { c: 3, d: 4 }) },
Foo { a: 5, b: Extra::A(Bar { c: 6, d: 7 }) },
],
}),
};
fn exec_foo(foo: &mut Foo, index: usize, parent: &Foo) {
foo.a += 1;
println!("foo.a: {:?}", foo.a);
println!("index: {:?}", index);
println!("parent: {:?}", parent);
}
iterate_foo(&mut foo_1, exec_foo);
}
The error message:
Compiling playground v0.0.1 (/playground)
error[E0502]: cannot borrow `*foo` as immutable because it is also borrowed as mutable
--> src/main.rs:30:62
|
28 | match &mut foo.b {
| ---------- mutable borrow occurs here
29 | Extra::B(baz) => {
30 | baz.children.iter_mut().enumerate().for_each(|(index, child)| {
| -------- ^^^^^^^^^^^^^^^^ immutable borrow occurs here
| |
| mutable borrow later used by call
31 | exec(child, index, foo);
| --- second borrow occurs due to use of `*foo` in closure
For more information about this error, try `rustc --explain E0502`.
error: could not compile `playground` (bin "playground") due to 1 previous error
any idea on how to make it works?
Thanks ahead.