Rust 借用指针和生命周期 [英] Rust borrowed pointers and lifetimes

查看:47
本文介绍了Rust 借用指针和生命周期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In my code I have a mutually recursive tree structure which looks something like the following:

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]
        } 
    }
}

但它不会按原样编译.修改它以使其这样做的最佳方法是什么?

but it doesn't compile as-is. What is the best way to modify it to make it do so?

推荐答案

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

Here is a version where the nodes can be modified from outside the tree, which I presume is what was asked for.

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> 的原因.Option 类型用于表示具有 Option>> 的潜在子项.

Rc is a reference counted pointer and allows a single object to have multiple owners. It doesn't allow mutation however, so a RefCell is required which allows runtime checked mutable borrowing. That's why the code uses Rc<RefCell<Node>>. The Option type is used to represent potential children with Option<Rc<RefCell<Node>>>.

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

Since, the Rc type auto dereferences, it's possible to directly call RefCell methods on it. These are borrow() and borrow_mut() which return a reference and mutable reference to the underlying Node. There also exist try_borrow() and try_borrow_mut() variants which cannot fail.

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

get_ref() is a method of the Option type which returns a reference to the underlying Rc<RefCell<Node>>. In a real peogram we would probably want to check whether the Option contains anything beforehand.

为什么原来的代码不行?引用 &T 意味着非所有权,因此其他东西必须拥有节点.虽然可以构建 &Node 类型的树,但不能修改树外的节点,因为一旦借用了对象,除了借物.

Why does the original code not work? References &T imply non-ownership, so something else would have to own the Nodes. While it would be possible to build a tree of &Node types, it wouldn't be possible to modify the Nodes outside of the tree because once borrowed, an object cannot be modified by anything else than the borrowing object.

这篇关于Rust 借用指针和生命周期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆