我需要使用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/