【发布时间】:2022-01-20 10:15:21
【问题描述】:
我对 Rust 非常陌生,对于一项任务,我必须实现一个名为“SortedContainer”的二叉树。我遇到的问题是数据以某种方式移动,我似乎无法让引用工作。
错误代码是E0507。它出现在 Sortedcontainer 实现的插入函数中的“match self.root”中。
Rust 建议 &self 但这会产生类型错误:他希望在 BTNode::insert(foundNode, age, name) 中找到一个 Box,但找到了一个引用。 foundNode 现在是错误。试图解除它不起作用(*foundNode)。这样做的原因是“发生移动是因为 *foundNode 的类型 Box<BTNode<i32, String>> 没有实现 Copy 特征。
这是我的代码:
type ChildNode<T,U> = Option<Box<BTNode<T,U>>>; //Define alias (type); prevents recursive type (= self-reference), points to heap (box). Optional (option)
pub struct BTNode<T,U>{
left: ChildNode<T,U>, //Box prevents recursive type/self-reference; points to object on the heap
right: ChildNode<T,U>,
age: T,
name: U
}
impl BTNode<i32, String>{
pub fn new(l: ChildNode<i32, String>, r: ChildNode<i32, String>, a: i32, n: String) -> Self{ //ChildNode very important, otherwise no unit. values allowed.
BTNode::<i32,String>{
left: l, right: r, age: a, name: n
}
}
pub fn insert(mut node: Box<BTNode<i32, String>>, age: i32, name: String) -> Box<BTNode<i32, String>>{
if age < node.age {
match node.left {
None => node.left = Some(Box::new(BTNode::new(None, None, age, name))),
Some(foundNode) => return BTNode::insert(foundNode, age, name),
}
} else if age > node.age { //This else keeps the "name" from going out of scope
match node.right {
None => node.right = Some(Box::new(BTNode::new(None, None, age, name))),
Some(foundNode) => return BTNode::insert(foundNode, age, name),
}
}
eprintln!("Undefined/Unimplemented behaviour: age already present in tree. Failed to insert into tree");
std::process::exit(0x0100); //Error code 0 on linux, 256 on Windows
}
}
pub struct SortedContainer<T,U>{
root: ChildNode<T,U>
}
impl SortedContainer <i32,String> { //Tree
pub fn new() -> Self{
SortedContainer::<i32,String>{
root: None,
}
}
pub fn insert(&mut self, age: i32, name: String) { //self is a keyword; self cannot be replaced by say "tree";
match self.root { //ERROR E0507 HERE. If &self, then error below
None => {
self.root = Some(Box::new(BTNode::new(None, None, age, name)));
},
Some(foundNode) => {
BTNode::insert(foundNode, age, name); //If &self, then foundNode has error E0308 mismatched types. Expected struct Box, found reference.
//If dereferenced, then error E0507 again.
}
}
}
}
编辑:这可能是一些相关信息。这就是我尝试使用 SortedContainer 以及测试它的方式。
fn main() {
let mut tree: tree::SortedContainer<i32, String> = tree::SortedContainer::new();
tree.insert(32, "Papa Johns".to_string()); //This works due to the self parameter in the function
tree.insert(24, "Johan".to_string());
tree.insert(8, "EvaBeva".to_string());
tree.insert(64, "PizzaLoverYesYes".to_string());
tree.print();
}
【问题讨论】:
-
在您的代码中注释掉
pub fn print(&self) {}不会改变错误 - play.rust-lang.org/…。您确定您没有更改任何其他内容吗? -
请记住,二叉树基本上是一组具有一些共同元素的链表,您应该阅读:Learn Rust With Entirely Too Many Linked Lists。
-
@Cerberus 你是对的,它消除了 Visual Studio Code 指示的所有错误,但它仍然给出编译器错误。然而,错误又是 E0507。它也出现在同一行,即来自 SortedContainer 实现中的插入函数的“匹配 self.root”。我正在编辑问题
-
None分支在您的insert函数中分配给一个字段但不返回值,因此执行将脱离if-else链并运行到您的流程结束逻辑。 (PS 改用panic!("age already present in tree");)