I am trying to implement a binary tree which, after reading other posts, seems to be a great way to test yourself against the borrow checker. The below code is reproduced here.
struct Node<T: Eq + PartialEq + Ord + PartialOrd> {
left: Option<Box<Node<T>>>,
right: Option<Box<Node<T>>>,
value: T
}
impl<T> Node<T>
where
T: Eq + PartialEq + Ord + PartialOrd,
{
fn new(value: T) -> Self {
Self {
left: None,
right: None,
value,
}
}
fn insert(&mut self, value: T) {
if value == self.value {
return;
}
let mut target = if value > self.value {
self.right
} else {
self.left
};
match target {
Some(ref mut t) => {
t.insert(value);
}
None => {
let new_node = Node::new(value);
*target = Some(Box::new(new_node));
}
}
}
}
And the error:
Compiling playground v0.0.1 (/playground)
error[E0614]: type `Option<Box<Node<T>>>` cannot be dereferenced
--> src/lib.rs:37:17
|
37 | *target = Some(Box::new(new_node));
| ^^^^^^^
For more information about this error, try `rustc --explain E0614`.
error: could not compile `playground` (lib) due to previous error
The error of course makes sense. I am trying to set something of type Option
to something else via dereferencing which isn't possible. What is confusing to me is how to handle this case. In the Some
case it seems obvious that I need to destructure the option with ref mut
to get the inner box of a node and then call insert
on it. However, in the None
case there is nothing to destructure to and I need to set the target itself. If I remove the dereference it will not set the pointed-to value itself.
I am not sure how to reorganize this code so that dereferencing will be allowed. I would appreciate any help!