rust - 为什么我会得到 "closure implements ` FnMut`,因此对捕获变量的引用无法逃脱闭包”?

标签 rust

我有一个通用的Interface特征。 Interface有一个method ,将使用动态调度来调用。具体来说,我将传递 Rc<RefCell<dyn Interface>> .

我有一个用例,我需要将调用包装到 method在一个闭包内。期望的行为是使用 input 调用闭包与调用 obj.method 相同与 input哪里obj实现Interface .

以下是我迄今为止的尝试。

use std::cell::RefCell;
use std::rc::Rc;

pub trait Interface<'p, T> {
    fn method<'s: 'p>(&'p self, input: &'s str) -> T;
}

fn wrap_interface_with_closure<'p, 's: 'p, T: 'p>(
    instance: Rc<RefCell<dyn Interface<'p, T>>>,
) -> impl FnMut(&'s str) -> T + 'p {
    move |input| (*instance).borrow().method(input)
}

这给了我以下错误:

error[E0716]: temporary value dropped while borrowed
   |
13 |     instance: Rc<RefCell<dyn Interface<'p, T>>>,
   |     -------- lifetime `'2` appears in the type of `instance`
14 | ) -> impl FnMut(&'s str) -> T + 'p {
15 |     move |input| (*instance).borrow().method(input)
   |                  ^^^^^^^^^^^^^^^^^^^^--------------
   |                  |                                |
   |                  |                                temporary value is freed at the end of this statement
   |                  creates a temporary which is freed while still in use
   |                  argument requires that borrow lasts for `'2`

error: lifetime may not live long enough
   |
13 |     instance: Rc<RefCell<dyn Interface<'p, T>>>,
   |     -------- lifetime `'2` appears in the type of `instance`
14 | ) -> impl FnMut(&'s str) -> T + 'p {
15 |     move |input| (*instance).borrow().method(input)
   |     ------------   ^^^^^^^^ closure capture requires that `'1` must outlive `'2`
   |     |
   |     lifetime `'1` represents this closure's body
   |
   = note: closure implements `FnMut`, so references to captured variables can't escape the closure

error: aborting due to 2 previous errors; 2 warnings emitted

当它说closure implements FnMut, so references to captured variables can't escape the closure时它谈论的是哪个捕获的变量?是说instance正在逃避?这是否意味着借钱正在逃逸?

最佳答案

您的特征需要&'p self,即对self的引用必须与'p相同。在你的闭包中,你调用 borrow():

(*instance).borrow()

您获得了对接口(interface)的引用,其生命周期仅在整个闭包期间持续 ('1)。但是,您的特征定义要求 self 的生命周期为 'p:

fn method<'s: 'p>(&'p self, input: &'s str) -> T;

因此,当您在闭包中调用 .method() 时,self 的生命周期将为 '1 (在闭包内有效),它的生命周期不够长,无法满足参数的生命周期 'p 。您可以通过删除 self 的要求来解决此问题:

fn method<'s: 'p>(&self, input: &'s str) -> T;

您仍然可以确保 input 比您的实例更长寿,因为 的 :'p 是您的 wrap_interface_with_closure< 的一部分 函数。

关于rust - 为什么我会得到 "closure implements ` FnMut`,因此对捕获变量的引用无法逃脱闭包”?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74296392/

相关文章:

git - 如何检查 HEAD 是否被标记

pattern-matching - Rust的比赛早破

rust - Rust嵌入式商店外围设备

rust - 将 tokio::task::JoinHandle 存储在 HashMap 中并从另一个任务访问它

rust - 为了向下转换一个特征对象,为什么它必须是静态的?

functional-programming - 如何创建 `FnOnce` 函数

polymorphism - 属于特征的对象的向量

multithreading - 在Vec上实现并行/多线程合并排序

rust - 获取向量尾部的惯用方法是什么?

iterator - 如果另一个特征是否实现,函数如何有条件地回退到特征?