这是代码(我也把它放在一个围栏中:http://is.gd/f9O3YG):
use std::mem;
pub struct Tree {
children: Vec<Option<Box<Tree>>>,
// other fields
}
impl Tree {
pub fn mutate(&mut self, x: i64) {
if self.is_base_case() {
// base case
unimplemented!();
} else {
// recursive case
let idx: usize = unimplemented!();
let mut subtree: Option<&mut Box<Tree>> = self.children.get_mut(idx).expect("child idx out of bounds").as_mut();
match subtree {
Some(ref mut subtree) => unimplemented!(),
None => {
let mut new_tree = Tree::new();
// recurse on the new tree here
mem::replace(&mut subtree, Some(&mut Box::new(new_tree)));
},
}
}
}
pub fn new() -> Tree {
unimplemented!();
}
fn is_base_case(&self) -> bool {
unimplemented!();
}
}
fn main() {
println!("it compiled!");
}
我正在编写一种数据结构,它是一种树。它将子树存储在Vec<Option<Box<Tree>>>
中,因为它不能保证每个位置都有一个子树。我正在尝试编写一个变异树的方法,如果它不存在,可能会创建一个子树。
正如您所看到的,如果您尝试在围栏中运行代码,我的方法不起作用。我不确定错误消息告诉我的是什么 - 我最好的猜测是它希望新创建的子树与第14行创建的子树具有相同的生命周期,以便更换是安全的。但是,我不确定如何让它具有那种生命。它也让我想到:既然新的子树也需要在数据结构的整个生命周期内有效,那么它的生命周期是否应该与父树相同?它可能需要更短,因为还有其他方法可以删除子树(我正在使用Option::take
,这很好用 - 我检查了文档的相反,但找不到一个)。我的方法是否有缺陷,如果没有,我应该如何修复我的实施?
答案 0 :(得分:4)
你试图将&mut
置于某个结构中,该结构的寿命比&mut
指向的结构长。这是一个简化的例子:
use std::mem;
pub struct Tree {
children: Vec<Option<Box<Tree>>>,
}
impl Tree {
pub fn mutate(&mut self, x: i64) {
let idx: usize = unimplemented!();
let mut subtree: Option<&mut Box<Tree>> =
self.children.get_mut(idx).unwrap().as_mut();
let mut new_tree = Tree::new();
mem::replace(&mut subtree, Some(&mut Box::new(new_tree)));
}
pub fn new() -> Tree {
unimplemented!();
}
}
fn main() {}
问题是&mut Box::new(...)
是临时引用,因此您不能将其复制到另一个结构中。您在as_mut
上使用Option
令人困惑;如果你只是不那么你的代码可以正常工作:
let mut subtree: &mut Option<Box<Tree>> =
self.children.get_mut(idx).unwrap();
let mut new_tree = Tree::new();
mem::replace(subtree, Some(Box::new(new_tree)));
Here's it in the larger context. You can simplify it a bit, too.