我是Rust的新手,在阅读了官方Rust Book的一些章节后,我开始编写一些数据结构的东西。我选择创建一个简单的二叉树并执行两次简单的预排序。所以我写了一个简单的程序:
struct TreeNode {
val: i32,
left: Option<Box<TreeNode>>,
right: Option<Box<TreeNode>>,
}
impl TreeNode {
fn new(val: i32, left: Option<Box<TreeNode>>, right: Option<Box<TreeNode>>) -> TreeNode {
TreeNode { val, left, right }
}
}
fn main() {
let root = TreeNode::new(
120,
Some(Box::new(TreeNode::new(
150,
Some(Box::new(TreeNode::new(180, None, None))),
Some(Box::new(TreeNode::new(40, None, None))),
))),
Some(Box::new(TreeNode::new(
110,
Some(Box::new(TreeNode::new(144, None, None))),
None,
))),
);
pre_order(Some(Box::new(root)));
pre_order(Some(Box::new(root)));
}
fn pre_order(root: Option<Box<TreeNode>>) {
match root {
None => {
return;
}
Some(root_node) => {
println!("{} ", root_node.val);
pre_order(root_node.left);
pre_order(root_node.right);
}
}
}
这个程序无法编译,因为第一个前序函数已经移动了根节点,所以第二个函数什么也没有得到。这是不对的。前序函数不应该吃它的根节点。我知道通过引用传递参数可以防止函数发生这种情况。所以我添加了一个引用...在什么之前?选项?盒子?树节点?我决定把它们都添加进去。所以我修改了函数如下:
fn pre_order(root: &Option<&Box<&TreeNode>>) {
match root {
None => {
return;
}
Some(root_node) => {
println!("{} ", root_node.val);
pre_order(&&&root_node.left);
pre_order(&&&root_node.right);
}
}
}
并改变了我称呼它的方式:
pre_order(&Some(&Box::new(&root)));
pre_order(&Some(&Box::new(&root)));
但是,检查工具警告我:
error[E0308]: mismatched types
--> src/main.rs:35:23
|
35 | pre_order(&&&root_node.left);
| --------- ^^^^^^^^^^^^^^^^^ expected enum `Option`, found reference
| |
| arguments to this function are incorrect
|
= note: expected reference `&Option<&Box<&TreeNode>>`
found reference `&&&Option<Box<TreeNode>>`
note: function defined here
--> src/main.rs:28:4
|
28 | fn pre_order(root: &Option<&Box<&TreeNode>>) {
| ^^^^^^^^^ ------------------------------
error[E0308]: mismatched types
--> src/main.rs:36:23
|
36 | pre_order(&&&root_node.right);
| --------- ^^^^^^^^^^^^^^^^^^ expected enum `Option`, found reference
| |
| arguments to this function are incorrect
|
= note: expected reference `&Option<&Box<&TreeNode>>`
found reference `&&&Option<Box<TreeNode>>`
note: function defined here
--> src/main.rs:28:4
|
28 | fn pre_order(root: &Option<&Box<&TreeNode>>) {
| ^^^^^^^^^ ------------------------------
For more information about this error, try `rustc --explain E0308`.
我很困惑.我怎么可能改变类型&&&Option<Box<TreeNode>>
到&Option<&Box<&TreeNode>>
?我不认为我这样做是正确的.我应该添加引用的哪一部分?选项,框或TreeNode?如何设计的pre_order函数,这样我就可以传递树节点的引用递归而不实际消耗它?我需要Rc,Refcell,寿命说明符或任何高级功能来做到这一点?
1条答案
按热度按时间wwtsj6pe1#
要解决这个问题,你需要理解装箱一个值也会将它移动到一个盒子中,也就是说,你不能两次装箱或 Package 一个选项相同的值(在这种情况下是
root
)。快速的解决方案是在创建时立即 Package 根:并将引用传递给函数:
Playground