How can I return a reference to something from inside a shared pointer (in this case Rc<RefCell<_>>
)? In the example below, I show how it can be done with just a regular mutable reference to self
, but if it becomes a shared pointer instead, the compiler gets angry that the return type has a missing lifetime specifier.
error[E0106]: missing lifetime specifier
--> src/main.rs:19:60
|
19 | fn add_to_shared(me: Rc<RefCell<Thing>>, item: i32) -> &i32 {
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
help: consider using the `'static` lifetime
|
19 | fn add_to_shared(me: Rc<RefCell<Thing>>, item: i32) -> &'static i32 {
| ^^^^^^^^
use std::cell::RefCell;
use std::rc::Rc;
struct Thing {
items: Vec<i32>,
}
impl Thing {
fn new() -> Self {
Thing { items: Vec::new() }
}
fn add_to_self(&mut self, item: i32) -> &i32 {
self.items.push(item);
self.items.last().unwrap()
}
// does not compile
fn add_to_shared(me: Rc<RefCell<Thing>>, item: i32) -> &i32 {
me.borrow().items.push(item);
me.borrow().items.last().unwrap()
}
}
fn main() {
let mut thing = Thing::new();
println!("{}", thing.add_to_self(10));
let mut rc = Rc::new(RefCell::new(Thing::new()));
println!("{}", rc.add_to_shared(20));
}
Why do I want to do this? I have a program that builds a tree-like structure with multiple ownership. One of the associated methods takes two nodes of the tree (each shared pointers) and bundles them together into another part of the tree. Each method returns a reference to the newly created node so that it can be conveniently logged out (see the example).
I was thinking I'd need to use lifetime annotations to get this to work, but I have not been able to find out how do apply this concept to the interior of a Rc<RefCell<_>>
type.