I have a data structure like this:
struct R {
hmhs: HashMap<i64, HashSet<i64>>,
}
impl R {
fn hs_for_hmhs(&mut self) -> &mut HashSet<i64> {
if let None = self.hmhs.get(&0) {
self.hmhs.insert(0, HashSet::new());
}
self.hmhs.get_mut(&0).unwrap()
}
fn iter_for_hmhs<'a>(&'a mut self) -> impl Iterator<Item = &'a i64> {
self.hs_for_hmhs().iter()
}
fn insert_for_hmhs(&mut self, i: i64) -> bool {
self.hs_for_hmhs().insert(i)
}
}
This seems to work, but all the methods require a mutable
reference to self
which is unfortunate. I tried to give
interior mutability a go:
struct S {
hmhs: RefCell<HashMap<i64, HashSet<i64>>>,
}
impl S {
fn hs_for_hmhs(&self) -> &HashSet<i64> {
if let None = self.hmhs.borrow().get(&0) {
self.hmhs.borrow_mut().insert(0, HashSet::new());
}
self.hmhs.borrow_mut().get_mut(&0).unwrap()
}
fn iter_for_hmhs(&mut self) -> impl Iterator<Item = &i64> {
self.hs_for_hmhs().iter()
}
fn insert_for_hmhs(&mut self, i: i64) -> bool {
self.hs_for_hmhs().insert(i)
}
}
However, I constantly seem to hit problems. Mostly some variety of How do I return a reference to something inside a RefCell without breaking encapsulation?
I have tried lots of variants here, but I am missing something fundamental in my understanding. Is there a way of achieving what I want?
use std::cell::RefCell;
use std::collections::{HashMap, HashSet};
struct R {
hmhs: HashMap<i64, HashSet<i64>>,
}
impl R {
fn hs_for_hmhs(&mut self) -> &mut HashSet<i64> {
if let None = self.hmhs.get(&0) {
self.hmhs.insert(0, HashSet::new());
}
self.hmhs.get_mut(&0).unwrap()
}
fn iter_for_hmhs<'a>(&'a mut self) -> impl Iterator<Item = &'a i64> {
self.hs_for_hmhs().iter()
}
fn insert_for_hmhs(&mut self, i: i64) -> bool {
self.hs_for_hmhs().insert(i)
}
}
struct S {
hmhs: RefCell<HashMap<i64, HashSet<i64>>>,
}
impl S {
fn hs_for_hmhs(&self) -> &mut HashSet<i64> {
if let None = self.hmhs.borrow().get(&0) {
self.hmhs.borrow_mut().insert(0, HashSet::new());
}
self.hmhs.borrow_mut().get_mut(&0).unwrap()
}
fn iter_for_hmhs(&self) -> impl Iterator<Item = &i64> {
self.hs_for_hmhs().iter()
}
fn insert_for_hmhs(&self, i: i64) -> bool {
self.hs_for_hmhs().insert(i)
}
}
fn main() {}
Compiler Message:
error[E0597]: borrowed value does not live long enough
--> src/main.rs:36:9
|
36 | self.hmhs.borrow_mut().get_mut(&0).unwrap()
| ^^^^^^^^^^^^^^^^^^^^^^ temporary value does not live long enough
37 | }
| - temporary value only lives until here
|
note: borrowed value must be valid for the anonymous lifetime #1 defined on the method body at 31:5...
--> src/main.rs:31:5
|
31 | / fn hs_for_hmhs(&self) -> &mut HashSet<i64> {
32 | | if let None = self.hmhs.borrow().get(&0) {
33 | | self.hmhs.borrow_mut().insert(0, HashSet::new());
34 | | }
35 | |
36 | | self.hmhs.borrow_mut().get_mut(&0).unwrap()
37 | | }
| |_____^