I store a container inside a RefCell. And I want to return a reference to an element from the method. But the element may be not present, so I need to return Option. I managed to write such a function, but it does not look good, at least it double-checks for the existence of the element and the second check is unwrap().
Can it be improved?
Also, I do not like that I can't just debug print the result, but that's a side question.
The core problem is that the returned iterator needs to hold:
Ref
A hash_map::Iter
The inner iterator needs to borrow from Ref, which isn't normally allowed. A handy exemption from that is a pinned async block. genawaiter wraps pinned async blocks and gives them an Iterator interface.
fn iter(&self) -> impl Iterator<Item = (u32, String)> + '_ {
let map = self.map.borrow();
genawaiter::rc::Gen::new(|co| async move {
let it = map.iter();
for (k, v) in it {
co.yield_((*k, v.clone())).await;
}
})
.into_iter()
}
fn main() {
let map = MyMap::default();
println!("get(0): {:?}", map.get(0).is_some());
map.insert(0, "aaa".to_string());
map.insert(10, "www".to_string());
println!("get(0): {:?}", *map.get(0).unwrap());
for i in map.iter() {
println!("iter: {:?}", i);
}
}
I was thinking of storing the Ref and the iterator together so that the iterator references the data that lives long enough. But that means creating a self-referential data structure, which is not easy in Rust also.
The only real reason not to return the Ref<'_, _> at that point is because you want to hide the implementation detail of that type. If you don't care about hiding the type of the HashMap in addition, you could just implement Deref.
RefCell/Ref is basically a single-thread runtime-checked Mutex/MutexGuard.[1] So this is basically going over why &Mutex<HashMap<_, _>> doesn't implement IntoIterator and so on: there's no way to pass back an intermediate lock that stays alive long enough. (And items have to be able to outlast the Iterator that doled them out, which is presumably why you had to clone in your generator.)
More like RwLock but most people are more familiar with locking and releasing Mutex. âŠī¸