rust - std::cell::Ref <T>和&T的区别

标签 rust

我需要使用RefCell来实现特定签名的功能。任务是:给定二叉树在特定深度d的节点列表,得出下一级别d + 1的节点列表。我有一个草稿解决方案,但由于出现以下错误而无法编译:

error[E0515]: cannot return value referencing local variable `node`
  --> src/lib.rs:31:5
   |
26 |         if let Some(child) = &node.left {
   |                               ---- `node` is borrowed here
...
31 |     new_level
   |     ^^^^^^^^^ returns a value referencing data owned by the current function
为什么我的代码会起作用:我只对next_level函数中的引用进行操作,因此,引用的拥有的输入向量将在执行结束时被删除这一事实应该不是问题-我指向的值仍然有效。我认为std::cell::Ref与普通ref等效,只是在运行时强制执行借用规则。
如果我将输入vec从Vec<Ref<TreeNode>>更改为Vec<&TreeNode>,则相同的代码也可以工作。为什么?两者有何不同?
完整的代码:
use std::cell::{RefCell, Ref};
use std::rc::Rc;

// Definition for a binary tree node.
#[derive(Debug, PartialEq, Eq)]
pub struct TreeNode {
    pub val: i32,
    pub left: Option<Rc<RefCell<TreeNode>>>,
    pub right: Option<Rc<RefCell<TreeNode>>>,
}


fn next_level(lvl: Vec<Ref<TreeNode>>) -> Vec<Ref<TreeNode>> {
    let mut new_level = vec![];
    for node in lvl {
        if let Some(child) = &node.left {
            let rf = child.borrow();
            new_level.push(rf);
        }
    }
    new_level
}

最佳答案

它因Ref代码而出错的原因是,新的Ref在输入的Ref内,因此,两个Ref都必须存在才能使其有效。但是,此函数仅返回一个Ref,因此会出错。另外,您不能一次返回两个Ref,因为一个依赖另一个。它使用&代码工作的原因是&不需要原始引用就可以继续存在,因为原始引用不需要像Ref那样销毁时就可以执行运行代码之类的事情。
我建议在这种情况下传递Vec<Rc<RefCell<TreeNode>>>:

use std::cell::{RefCell, Ref};
use std::rc::Rc;

// Definition for a binary tree node.
#[derive(Debug, PartialEq, Eq)]
pub struct TreeNode {
    pub val: i32,
    pub left: Option<Rc<RefCell<TreeNode>>>,
    pub right: Option<Rc<RefCell<TreeNode>>>,
}


fn next_level(lvl: Vec<Rc<RefCell<TreeNode>>>) -> Vec<Rc<RefCell<TreeNode>>> {
    let mut new_level = vec![];
    for node in lvl {
        if let Some(child) = &node.borrow().left {
            new_level.push(child.clone());
        }
    }
    new_level
}

关于rust - std::cell::Ref <T>和&T的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65383195/

相关文章:

rust - 如何从枚举值获取重命名的枚举名称?

cassandra - 如何将 actix_web 与 cassandra-sys-rs 连接池一起使用?

rust - Visitor 特性如何只允许部分实现?

rust - 如何在 actix 处理程序中设置查询参数的默认选项?

arrays - 暂时将 [u8] 转化为 [u16]

struct - 访问枚举内的结构

rust - 在 Rust 中运行外部进程

compiler-errors - 奇怪地重复出现的通用特征模式 : overflow evaluating the requirement

rust - 如何确定是否将 .clone() 和 .cloned() 与迭代器一起使用

rust - 如何在 Rust 中连接两个切片?