Rust借用指针和生命周期

use*_*040 5 rust

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

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]
        } 
    }
}
Run Code Online (Sandbox Code Playgroud)

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

A.B*_*.B. 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);
}
Run Code Online (Sandbox Code Playgroud)

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

由于 Rc 类型自动取消引用,因此可以直接调用它的 RefCell 方法。它们是borrow()和 ,borrow_mut()它们返回对底层 Node 的引用和可变引用。也存在不会失败的变体try_borrow()try_borrow_mut()

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

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