我对Rust很陌生,对于一个赋值,我必须实现一个名为"的二进制树;排序容器";。我遇到的问题是,数据以某种方式移动,我似乎无法使引用正常工作。
错误代码为E0507。它出现在";match self.root";在Sortedcontainer实现的插入函数中。
Rust建议&self,但这会创建一个类型错误:他希望在BTNode::insert(foundNode,age,name(中有一个Box,但找到了一个引用。foundNode现在是错误。尝试取消隔离它不起作用(*foundNode(。其原因是;发生移动是因为*foundNode
具有不实现Copy
特性的类型Box<BTNode<i32, String>>
。
这是我的代码:
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();
}
当您在SortedContainer::insert
中解构self.root
并从中提取foundNode
时,有3个选项:
- 要么按值取值(这是默认值,也称为"移动"(
- 或者您制作一个拷贝("克隆"(
- 或者你把它作为参考
情况1不是你想要的,因为它会将foundNode从self.root中分离出来,并使其无效,但你想在调用insert后再次使用self.root。
情况2可能不是您想要的,因为复制整个子树并不是一个很好的性能。
所以最好传递一个引用。在这种情况下,您还需要调整BTNode::insert
以接受引用(目前在您的版本中,它需要一个值(:
pub fn insert(node: &mut Box<BTNode<i32, String>>, ...