Это минимальная воспроизводимая ошибка, взятая из интерпретатора, который я пишу. Насколько я понимаю, я должен иметь возможность вернуть ссылку на поле структуры в 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_rcc
принадлежит функцииget_property
именно потому, что поскольку она была перемещена туда, и когда она выйдет за пределы области действия, значение, ранее известное какglobal_object
, будет удалено. Бывают ситуации, когда Rust чрезмерно консервативен: это не одна из них. В вашем коде есть ошибка использования после освобождения, и компилятор любезно предупреждает вас об этом, а не позволяет вам вызывать UB. - person trentcl   schedule 31.03.2021