Reputation: 19181
I'm having trouble understanding how to idiomatically find and append to or create a new vector if the value is part of a data structure, in this case a Red Black tree.
I'm using this Red Black Tree implementation and the plan is to grab a mutable reference to the value which I will append to if it exists (not None
) and create a new vector and move it to the RBTree
if there is no value for the key. My code looks like this, slightly altered for brevity so excuse any careless errors:
struct Obj {
tree: RBTree<i32, Vec<String>>,
}
let mut obj = Obj {
tree: RBTree::new(),
};
let k = 5;
let v = "whatever";
match obj.tree.get_mut(k) {
None => {
let mut vec: Vec<Node> = Vec::new();
vec.push(v);
book.tree.insert(k, vec);
}
Some(vec) => vec.push(v),
}
The problem is that I'm getting a mutable reference to the tree when I check for existence because if it does exist, I want to mutate it by appending to the vector. However, if it does not exist, I want to insert a new node which tries to do a mutable borrow so I get a "second mutable borrow occurs here" on this line book.tree.insert(k, vec);
.
I would love some insight into how to perform this find or create so that it compiles and is thread safe. I guess it's also possible the library I'm using has problems. Not yet qualified to comment on that.
Upvotes: 0
Views: 142
Reputation: 100180
In such cases the workaround is to move the mutating code outside of get_mut()
's scope.
let needs_insert = match obj.tree.get_mut(k) {
None => true,
Some(vec) => {
vec.push(v);
false
}
};
if needs_insert {
book.tree.insert(k, vec![v]);
}
Upvotes: 0