首页 文章

Rust借用指针和生命周期

提问于
浏览
5

在我的代码中,我有一个相互递归的树结构,如下所示:

enum Child<'r> {
    A(&'r Node<'r>),
    B, 
    C
}

struct Node<'r> {
    children : [&'r Child<'r>,..25]
}

impl <'r>Node<'r> {
    fn new() -> Node {
        Node {
            children : [&B,..25]
        } 
    }
}

但它不按原样编译 . 修改它的最佳方法是什么?

1 回答

  • 4

    这是一个可以从树外修改节点的版本,我认为这是要求的 .

    use std::rc::Rc;
    use std::cell::RefCell;
    
    struct Node {
        a : Option<Rc<RefCell<Node>>>,
        b : Option<Rc<RefCell<Node>>>,
        value: int
    }
    
    impl Node {
        fn new(value: int) -> Rc<RefCell<Node>> {
            let node = Node {
                a: None,
                b: None,
                value: value
            };
            Rc::new(RefCell::new(node))
        }
    }
    
    
    fn main() {
        let first  = Node::new(0);
        let second = Node::new(0);
        let third  = Node::new(0);
    
        first.borrow_mut().a = Some(second.clone());
        second.borrow_mut().a = Some(third.clone());
    
        second.borrow_mut().value = 1;
        third.borrow_mut().value = 2;
    
        println!("Value of second: {}", first.borrow().a.get_ref().borrow().value);
        println!("Value of third: {}",  first.borrow().a.get_ref().borrow().a.get_ref().borrow().value);
    }
    

    Rc 是引用计数指针,允许单个对象拥有多个所有者 . 但它不允许突变,因此需要 RefCell 允许运行时检查可变借用 . 这就是代码使用 Rc<RefCell<Node>> 的原因 . Option类型用于表示具有 Option<Rc<RefCell<Node>>> 的潜在子项 .

    由于Rc类型自动解除引用,因此可以直接在其上调用RefCell方法 . 这些是 borrow()borrow_mut() ,它们返回对底层节点的引用和可变引用 . 还存在 try_borrow()try_borrow_mut() 变体,这些变体不会失败 .

    get_ref() 是Option类型的方法,它返回对底层 Rc<RefCell<Node>> 的引用 . 在真实的peogram中,我们可能想要检查Option是否包含任何事先 .

    为什么原始代码不起作用?引用 &T 意味着非所有权,因此其他东西必须拥有节点 . 虽然可以构建一个 &Node 类型的树,但是不可能修改树外的节点,因为一旦借用,对象就不能被借用对象以外的任何东西修改 .

相关问题