如何替换 Vec 中的选项?

How can I replace an Option within a Vec?

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

您正试图将 &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(...)是一个临时引用,所以你不能直接将它复制到另一个结构中。您在 Option 上使用 as_mut 令人困惑;如果你只是这样做你的代码工作正常:

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.