So I have some code like this:
use std::borrow::Borrow;
use std::cell::RefCell;
use std::collections::HashMap;
use std::ops::Index;
use std::rc::Rc;
struct Data {
// ...
}
struct TableTreeNode {
father: Option<Rc<RefCell<TableTreeNode>>>,
table: HashMap<String, Data>,
}
impl Index<&str> for TableTreeNode {
type Output = Data;
fn index(&self, index: &str) -> &Self::Output {
if self.table.contains_key(index) {
self.table.index(index)
} else {
//recursively goes up
let father: &RefCell<TableTreeNode> = self.father.as_ref().expect("not found");
father.borrow().index(index)
}
}
}
It fails on compile:
error[E0515]: cannot return reference to temporary value
--> xxx.rs:25:13
|
25 | father.borrow().index(index)
| ---------------^^^^^^^^^^^^^
| |
| returns a reference to data owned by the current function
| temporary value created here
I have no clue to solve this. How would a borrow from a RefCell
could be a temporary variable? If I'm doing this wrong, what's the right way to implement these?
Because RefCell::borrow()
returns aRef
guard. This guard implements Deref
, and when it is dropped it marks the RefCell
as no longer borrowed.
Generally, you cannot hide a RefCell
across API boundaries if you use it. You have to return a Ref<Something>
or RefMut<Something>
instead os &[mut] Something
. And because the signature of Index
is constant and expecting a reference, that means you cannot implement Index
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.