【发布时间】:2021-03-30 21:04:32
【问题描述】:
这是一个最小的可重现错误,取自我正在编写的解释器。据我了解,我应该能够返回对 RefCell 中结构字段的引用,因为 RefCell 有足够的生命周期。但是,编译器告诉我我不能返回对当前函数拥有的值的引用,坦率地说,这让我感到困惑。
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
#[derive(Debug)]
enum Value {
Number,
String,
}
struct Object {
pub properties: HashMap<String, Value>,
}
impl Object {
pub fn get_property(&mut self, name: &str) -> Option<&mut Value> {
self.properties.get_mut(name)
}
}
fn get_property(global_object_rcc: Rc<RefCell<Object>>, name: &str) -> Option<&mut Value> {
// Rust cannot verify that this Rc isn't the last Rc that just got moved into this function?
global_object_rcc.borrow_mut().get_property(name)
}
fn main() {
// Construct global object
let mut global_object = Object {
properties: HashMap::new(),
};
// Give it a property
global_object
.properties
.insert("Test".to_owned(), Value::Number);
// Put it in a Rc<RefCell> (rcc) for sharing
let global_object_rcc = Rc::new(RefCell::new(global_object));
// Get a reference to its property, should be valid because the reference only needs to live
// as long as the global_object
let property = get_property(global_object_rcc, "Test");
dbg!(&property);
}
这是我收到的错误消息:
error[E0515]: cannot return value referencing temporary value
--> src\main.rs:23:5
|
23 | global_object_rcc.borrow_mut().get_property(name)
| ------------------------------^^^^^^^^^^^^^^^^^^^
| |
| returns a value referencing data owned by the current function
| temporary value created here
【问题讨论】:
-
global_object_rccis 归get_property函数所有,正是因为它被移到了那里,当它超出范围时,值以前称为global_object将被删除。在某些情况下,Rust 过于保守:这不是其中之一。您的代码有一个 use-after-free 错误,编译器会优雅地提醒您,而不是让您调用 UB。 -
或者How do I borrow a RefCell<HashMap>, find a key, and return a reference to the result?(我还没有重复,因为代码中存在多个与借用相关的问题,我不确定这是您问题的重点)
标签: rust borrow-checker