Reputation: 11
I have such a piece of code:
struct Node {
value: u32,
left: Option<Box<Node>>,
right: Option<Box<Node>>,
}
fn traverse(last_nodes: &mut VecDeque<&Node>, result: &mut Vec<u32>) {
if last_nodes.len() == 0 {
return;
}
let mut childrens = VecDeque::new();
while let Some(node) = last_nodes.pop_front() {
result.push(node.value);
if let Some(n) = &node.left {
childrens.push_back(&*n);
}
if let Some(n) = &node.right {
childrens.push_back(&*n);
}
}
traverse(&mut childrens, result)
}
pay more attention to below code, I want childrens
to be a VecDeque<&Node> type
let mut childrens = VecDeque::new();
however, it gets a result like VecDeque<&Box<Node>>
because of below code and inference of compiler
childrens.push_back(&*n);
but if we correct the above code to be more definate, we can get our codes passing the compiler
let mut childrens:VecDeque<&Node> = VecDeque::new();
I don't know if it is the imperfection of compiler
Upvotes: 0
Views: 51
Reputation: 70900
The compiler is correct. The type of &node.left
and &node.right
is &Option<Box<Node>>
. As such, matching it against Some(n)
makes n
has type &Box<Node>
, by match ergonomics. So &*n
is also &Box<Node>
, and you're creating a VecDeque<&Box<Node>>
.
However, &Box<Node>
can be coerced to &Node
via deref coercion. So, if the compiler knows the type of the VecDeque
is VecDeque<&Node>
, and so it expects push_back()
to take &Node
, it will coerce &Box<Node>
to that and everything will work perfectly.
Upvotes: 4