如何更换Vec中的选项?

时间:2015-08-21 18:05:15

标签: rust lifetime

这是代码(我也把它放在一个围栏中: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,这很好用 - 我检查了文档的相反,但找不到一个)。我的方法是否有缺陷,如果没有,我应该如何修复我的实施?

1 个答案:

答案 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.