我如何 return 一个引用了 RefCell 中某些内容的迭代器?
How do I return an iterator that has a reference to something inside a RefCell?
我正在尝试创建一个方法,该方法 return 是 RefCell
内装箱的 HashMap
值的迭代器,但我遇到了一个错误Ref
return 由 RefCell::borrow
编辑的时间不够长,无法从方法中 return 编辑迭代器。这是我的代码:
use std::rc::Rc;
use std::cell::RefCell;
use std::collections::HashMap;
use std::collections::hash_map::Values;
struct Foo {
map: Rc<RefCell<HashMap<i32, i32>>>,
}
impl Foo {
fn iter(&self) -> Values<i32, i32> {
self.map.borrow().values()
}
}
fn main() {
let foo = Foo {
map: Rc::new(RefCell::new(HashMap::new()))
};
for v in foo.iter() {
println!("{}", v)
}
}
编译错误:
rustc 1.15.1 (021bd294c 2017-02-08)
error: borrowed value does not live long enough
--> <anon>:12:9
|
12 | self.map.borrow().values()
| ^^^^^^^^^^^^^^^^^ does not live long enough
13 | }
| - temporary value only lives until here
|
建议创建一个 guard 封装 Ref
并提供访问底层值的接口,但我需要做的是 return 一个迭代器对象(Values<'a, K, V>
) 已经封装了对 HashMap
的简单引用。
我的主要问题是我有一个运行时跟踪引用 Ref<T>
而我需要一个简单的引用来创建迭代器。 Ref::map
公开了一个简单的映射引用,但它需要映射器函数到 return 另一个引用,这在这里是不可能的。我应该重做整个迭代器功能以使用 Ref
还是有更好的方法?
你不能这样做。
最终的问题是 std::collections::hash_map::Values
有引用,但你没有 "just" 引用。你有智能指针 Ref
.
我知道的最简单的解决方案是反转代码:
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)
}
})
}
在这里,Values
迭代器不再需要比 borrow
的结果更有效,因此没有额外的复杂性。
如果您不介意泄露您的实现,您可以 return Ref
:
impl Foo {
fn iter(&self) -> Ref<'_, HashMap<i32, i32>> {
self.map.borrow()
}
}
for v in foo.iter().values() {
println!("{}", v)
}
在较新版本的 Rust 中,您可以 return 实现 Deref
:
的未命名类型
use std::ops::Deref;
impl Foo {
fn iter(&self) -> impl Deref<Target = HashMap<i32, i32>> + '_ {
self.map.borrow()
}
}
另请参阅:
我正在尝试创建一个方法,该方法 return 是 RefCell
内装箱的 HashMap
值的迭代器,但我遇到了一个错误Ref
return 由 RefCell::borrow
编辑的时间不够长,无法从方法中 return 编辑迭代器。这是我的代码:
use std::rc::Rc;
use std::cell::RefCell;
use std::collections::HashMap;
use std::collections::hash_map::Values;
struct Foo {
map: Rc<RefCell<HashMap<i32, i32>>>,
}
impl Foo {
fn iter(&self) -> Values<i32, i32> {
self.map.borrow().values()
}
}
fn main() {
let foo = Foo {
map: Rc::new(RefCell::new(HashMap::new()))
};
for v in foo.iter() {
println!("{}", v)
}
}
编译错误:
rustc 1.15.1 (021bd294c 2017-02-08)
error: borrowed value does not live long enough
--> <anon>:12:9
|
12 | self.map.borrow().values()
| ^^^^^^^^^^^^^^^^^ does not live long enough
13 | }
| - temporary value only lives until here
|
Ref
并提供访问底层值的接口,但我需要做的是 return 一个迭代器对象(Values<'a, K, V>
) 已经封装了对 HashMap
的简单引用。
我的主要问题是我有一个运行时跟踪引用 Ref<T>
而我需要一个简单的引用来创建迭代器。 Ref::map
公开了一个简单的映射引用,但它需要映射器函数到 return 另一个引用,这在这里是不可能的。我应该重做整个迭代器功能以使用 Ref
还是有更好的方法?
你不能这样做。
最终的问题是 std::collections::hash_map::Values
有引用,但你没有 "just" 引用。你有智能指针 Ref
.
我知道的最简单的解决方案是反转代码:
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)
}
})
}
在这里,Values
迭代器不再需要比 borrow
的结果更有效,因此没有额外的复杂性。
如果您不介意泄露您的实现,您可以 return Ref
:
impl Foo {
fn iter(&self) -> Ref<'_, HashMap<i32, i32>> {
self.map.borrow()
}
}
for v in foo.iter().values() {
println!("{}", v)
}
在较新版本的 Rust 中,您可以 return 实现 Deref
:
use std::ops::Deref;
impl Foo {
fn iter(&self) -> impl Deref<Target = HashMap<i32, i32>> + '_ {
self.map.borrow()
}
}
另请参阅: