So, I was writing Binary Search tree as below
type Link<T> = Option<Box<Node<T>>>;
struct Node<T> {
elem: T,
left: Link<T>,
right: Link<T>,
}
impl<T: Ord> Node<T> {
pub fn new(elem: T) -> Self {
Node { elem, left: None, right: None }
}
pub fn push(&mut self, elem: T) {
if self.elem < elem {
self.right = self.right.take().map_or(
Option::Some(Box::new(Node::new(elem))),
|mut node| {
node.push(elem);
Option::Some(node)
}
);
} else {
self.left = self.left.take().map_or(
Option::Some(Box::new(Node::new(elem))),
|mut node| {
node.push(elem);
Option::Some(node)
}
);
}
}
}
but the compiler threw me an error. So I wrote like this
type Link<T> = Option<Box<Node<T>>>;
struct Node<T> {
elem: T,
left: Link<T>,
right: Link<T>,
}
impl<T: Ord> Node<T> {
pub fn new(elem: T) -> Self {
Node { elem, left: None, right: None }
}
pub fn push(&mut self, elem: T) {
if self.elem < elem {
self.right = match self.right.take() {
Some(mut node) => {node.push(elem); Option::Some(node)},
None => Option::Some(Box::new(Node::new(elem)))
}
} else {
self.left = match self.left.take() {
Some(mut node) => {node.push(elem); Option::Some(node)},
None => Option::Some(Box::new(Node::new(elem)))
}
}
}
}
It successfully compiled. Based on the semantics both are exactly same thing. How couldn't it resolve ownership in the first one but successfully resolved in latter?
And can we write code like in the first one without breaking any ownership rules? If so how?
And lastly this is the code I tried to write completely on my own after learning about rust with too many linked list. Can you give me suggestions like what be made better?