我的结构中有一个 RefCell
,我想访问和修改它。但是,我可以访问此 RefCell
的唯一方法是使用闭包。因此,我想从闭包中返回一个 mutable reference (RefMut
),我可以在封闭范围内使用和修改它。
{
let mut state_ref: RefMut<_> = self.dialog.call_on_name("dirview", |view: &mut Canvas<RefCell<FileDialogState>>| {
let state: &RefCell<FileDialogState> = view.state_mut();
state.borrow_mut()
}).unwrap();
state_ref.foo = bar;
// Mutable reference to RefCell should cease to exist here
}
然而,编译器抱怨我返回的 RefMut
比我创建它的闭包的生命周期长。
尽管如此,我还是看到了一些与我想要实现的类似的代码——例如 here:
impl Backend {
pub fn init() -> ... {
let stdout = RefCell::new(BufWriter::new(io::stdout()));
...
}
fn stdout_mut(&self) -> RefMut<BufWriter<Stdout>> {
self.stdout.borrow_mut()
}
这两个用例有什么区别?我缺少什么才能返回 RefMut
引用?
答案 0 :(得分:0)
RefCell
动态检查共享的可变访问,但它不动态管理整个单元格的所有权(这是 {{1} })。 Rc
或 Ref
仅在底层 RefMut
存在时才有效,这就是您不能从此闭包返回 RefCell
的原因: RefMut
将继续存在的代码结构。 (可能有,如果 RefCell
的类型为返回的引用指定了足够长的生命周期,但显然没有。)
在第二种情况下,.state_mut()
省略了生命周期,它将返回的 stdout_mut
的生命周期参数链接到 RefMut
的生命周期,这提供了必要的保证。 (如果您将 lint 设置更改为 &self
,那么每当用户定义类型中的生命周期参数被省略时,您都会收到警告,这有助于更清楚地说明这一点。)
要在第一种情况下解决您的问题,您可以:
改变你的结构,让它有 #[warn(elided_lifetimes_in_paths)]
而不是只有 Rc<RefCell<_>>
。然后你可以从闭包中返回 RefCell<_>
,然后借用它。
借用并在闭包内进行更改。