简体   繁体   English

Rust借用了指针和生命周期

[英]Rust borrowed pointers and lifetimes

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 is a reference counted pointer and allows a single object to have multiple owners. Rc是引用计数的指针,并允许单个对象具有多个所有者。 It doesn't allow mutation however, so a RefCell is required which allows runtime checked mutable borrowing. 但是,它不允许突变,因此需要RefCell ,它允许运行时检查可变借用。 That's why the code uses Rc<RefCell<Node>> . 这就是代码使用Rc<RefCell<Node>> The Option type is used to represent potential children with Option<Rc<RefCell<Node>>> . Option类型用于通过Option<Rc<RefCell<Node>>>表示潜在的子代。

Since, the Rc type auto dereferences, it's possible to directly call RefCell methods on it. 由于Rc类型会自动取消引用,因此可以直接在其上调用RefCell方法。 These are borrow() and borrow_mut() which return a reference and mutable reference to the underlying Node. 它们是borrow_mut() borrow()borrow_mut() ,它们返回对基础节点的引用和可变引用。 There also exist try_borrow() and try_borrow_mut() variants which cannot fail. 还存在不会失败的try_borrow()try_borrow_mut()变体。

get_ref() is a method of the Option type which returns a reference to the underlying Rc<RefCell<Node>> . get_ref()是Option类型的方法,该方法返回对基础Rc<RefCell<Node>>的引用。 In a real peogram we would probably want to check whether the Option contains anything beforehand. 在实际的Peogram中,我们可能需要事先检查Option是否包含任何内容。

Why does the original code not work? 为什么原始代码不起作用? References &T imply non-ownership, so something else would have to own the Nodes. 引用&T非所有权,因此必须拥有其他节点。 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. 虽然可以构建&Node类型的树,但无法修改树外的Node,因为一旦借用后,除了借用对象外,其他任何对象都无法修改对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM