rust - 从闭包中返回时的RefMut生命周期错误

标签 rust lifetime refcell

我的结构中有一个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引用?

最佳答案

RefCell动态检查共享的可变访问,但不能动态管理整个单元的所有权(这是Rc之类的工作)。 RefRefMut仅在存在底层RefCell的情况下才有效,这就是为什么您不能从此闭包返回RefMut的原因:在该代码的结构中无法保证RefCell会继续存在。 (如果.state_mut()的类型为返回的引用指定了足够长的生存期,则可能存在,但是显然没有。)
在第二种情况下,stdout_mut消除了生存期,该生存期将返回的RefMut的生存期参数链接到&self的生存期,从而提供了必要的保证。 (如果将 Lint 设置更改为#[warn(elided_lifetimes_in_paths)],则当用户定义类型的生命周期参数被删除时,您将收到一条警告,这可以使这一点更加清楚。)
要在第一种情况下解决您的问题,您可以:

  • 更改结构,使其具有Rc<RefCell<_>>而不是RefCell<_>。然后,您可以从闭包中返回Rc::clone(view.state_mut()),然后再借用它。
  • 借用并在闭包内进行更改。
  • 关于rust - 从闭包中返回时的RefMut生命周期错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65675881/

    相关文章:

    rust - Rust 中的字符串连接

    rust - 返回添加两个泛型的结果时类型不匹配

    c - 设置指向在 C 中的局部范围内声明的变量的指针

    rust - Rust中的“cannot return value referencing temporary value”和内部可变性

    methods - 如何在 Rust 中将对象用作其自身方法的参数?

    error-handling - 如何手动返回一个Result<(), Box<dyn Error>>?

    rust - 用非常简单的术语来说,什么是生命周期省略?

    javascript - Cordova 中 javascript 变量的生命周期

    rust - 重写函数以使用特征时借用内容时出错

    rust - 如何返回对 RefCell<Option<T>>> 内部数据的引用?