gpt4 book ai didi

reference - 我如何返回一个引用了 RefCell 中某些内容的迭代器?

转载 作者:行者123 更新时间:2023-11-29 08:30:49 26 4
gpt4 key购买 nike

我正在尝试创建一个方法,该方法返回一个遍历 HashMap 值的迭代器装在 RefCell 内,但我在 Ref 处遇到错误由 RefCell::borrow 返回没有足够长的时间从方法返回迭代器。这是我的代码:

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
|

How do I return a reference to something inside a RefCell without breaking encapsulation?建议创建一个封装 Ref 的守卫并提供一个用于访问底层值的接口(interface),但我需要做的是返回一个迭代器对象 ( Values<'a, K, V> ),它已经封装了对 HashMap 的简单引用。 .

我的主要问题是我有一个运行时跟踪引用 Ref<T>而我需要一个简单的引用来创建一个迭代器。 Ref::map公开了一个用于映射的普通引用,但它需要映射器函数返回另一个在这里不可能的引用。我是否应该重做整个迭代器功能以使用 Ref或者有更好的方法吗?

最佳答案

你不能这样做。

最终的问题是 std::collections::hash_map::Values 持有一个引用,但你没有“只是”一个引用。你有智能指针 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 的结果长寿,因此没有额外的复杂性。

如果您愿意泄露您的实现,您可以返回 Ref:

impl Foo {
fn iter(&self) -> Ref<'_, HashMap<i32, i32>> {
self.map.borrow()
}
}
for v in foo.iter().values() {
println!("{}", v)
}

在较新版本的 Rust 中,您可以返回一个实现了 Deref 的未命名类型:

use std::ops::Deref;

impl Foo {
fn iter(&self) -> impl Deref<Target = HashMap<i32, i32>> + '_ {
self.map.borrow()
}
}

另见:

关于reference - 我如何返回一个引用了 RefCell 中某些内容的迭代器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58383014/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com