rust - 从关闭返回时的 RefMut 生命周期错误
问题描述
我的结构中有一个RefCell
要访问和修改的结构。但是,我可以访问它的唯一方法RefCell
是使用闭包。因此,我想从闭包中返回一个可变引用( 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
我返回的生命周期超过了我创建它的闭包的生命周期。
尽管如此,我还是看到了与我想要实现的功能类似的代码——例如这里:
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
)。A Ref
orRefMut
仅在底层RefCell
存在时才有效,这就是为什么您不能RefMut
从此闭包中返回 the 的原因:该代码的结构中不能保证 theRefCell
将继续存在。(如果类型.state_mut()
为返回的引用指定了足够长的生命周期,则可能存在,但显然它没有。)
在第二种情况下,stdout_mut
省略了将返回的生命周期参数链接到RefMut
的生命周期的生命周期&self
,这提供了必要的保证。(如果您将 lint 设置更改为#[warn(elided_lifetimes_in_paths)]
then ,则每当用户定义类型中的生命周期参数被忽略时,您都会收到警告,这有助于使这一点更清晰。)
要在第一种情况下解决您的问题,您可以:
将您的结构更改为 have
Rc<RefCell<_>>
而不仅仅是RefCell<_>
. 然后你可以Rc::clone(view.state_mut())
从关闭中返回,然后再借用它。在关闭期间借用并进行更改。
推荐阅读
- node.js - 将 Node.js 页面部署到 AWS Elastic Beanstalk 后出现“hell.php”错误和“502 Bad Gateway”错误
- c# - ASP.NET Core 2.1 - 脚手架不生成任何文件
- function - 事件场景内的电晕功能位置
- r - 在 R 中使用聚合时如何保留其他列?
- django - 使用 Gunicorn 和 Nginx 在一个 Droplet 上运行两个 Django 项目
- r - 使用 mutate_at 缩短多个 dplyr 变异?
- php - 喜欢 jQuery 求和值
- javascript - 为什么我不能将图表添加到动态插入的 svg 元素?
- r - R,ImageMagick:如何在动画中的每个循环后添加延迟
- c# - 如何根据访问级别显示菜单选项?