You cannot do this.
The ultimate problem is that std::collections::hash_map::Values
holds a reference, but you don't have "just" a reference. You have the smart pointer Ref
.
The easiest solution I know of is to invert the code:
impl Foo {
fn with_iter<F, T>(&self, f: F) -> T
where
F: FnOnce(Values<i32, i32>) -> T,
{
f(self.map.borrow().values())
}
}
fn main() {
let foo = Foo {
map: Rc::new(RefCell::new(HashMap::new())),
};
foo.with_iter(|i| {
for v in i {
println!("{}", v)
}
})
}
Here, the Values
iterator no longer needs to outlive the result of borrow
, so there's no additional complexity.
If you are OK with leaking your implementation, you can return the Ref
:
impl Foo {
fn iter(&self) -> Ref<'_, HashMap<i32, i32>> {
self.map.borrow()
}
}
for v in foo.iter().values() {
println!("{}", v)
}
In newer versions of Rust, you can return an unnamed type that implements Deref
:
use std::ops::Deref;
impl Foo {
fn iter(&self) -> impl Deref<Target = HashMap<i32, i32>> + '_ {
self.map.borrow()
}
}
See also:
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…