0

我使用以下代码在render::exec每次发生RedrawRequested事件时运行我的函数(由 Glium 发布):

event_loop.run(move |event, _, control_flow| {
    match event {
        Event::RedrawRequested(_) => {
            let mut target = display.draw();
            render::exec(&mut target, &mut ctx, &font, &mut cache);
            target.finish().unwrap();
        }

        // ...

        _ => ()
    }
});

问题是,我在&font参考中收到以下错误:

borrowed data cannot be stored outside of its closure

font确实是在调用之前创建的event_loop.run,因为它是rusttype::Font我需要的一个结构,以便在我的 Glium 应用程序中呈现文本。我知道,由于这是一个move闭包,因此数据font将在其末尾被释放,因此借用检查器不允许font在闭包之外创建,因为不能确保闭包不会' t 被多次调用(实际上,它多次调用)。

我试图通过删除move关键字来规避这一点,但是我从闭包内部借用的每个变量都会触发以下错误:

closure may outlive the current function, but it borrows `ctx`, which is owned by the current function
may outlive borrowed value `ctx`

我知道,由于借用检查器无法确保这些变量至少与闭包一样长,因此它不允许从前者内部引用后者。

因此,我需要一种方法来确保借用检查器这些变量的持续时间至少与闭包一样长。通常这样做的一种方法是将它们作为参数传递给闭包,但实际上我无法更改传递的参数列表,因为我使用event_loop.run的是具有以下签名的 :

pub fn run<F>(self, event_handler: F) -> !
where F: 'static + FnMut(Event<'_, T>, &EventLoopWindowTarget<T>, &mut ControlFlow)

我浏览了 Glutin 文档,但找不到将任何数据存储到EventLoop(这是取消引用EventLoopWindowTarget提供的类型)的方法,也找不到ControlFlow作为参数传递的 。

4

1 回答 1

1

font 确实是在调用 event_loop.run 之前创建的,因为它是一个 rusttype::Font 结构,我需要它来在我的 Glium 应用程序中呈现文本。我知道,由于这是一个移动闭包,来自字体的数据将在其末尾被释放,因此借用检查器不允许在闭包之外创建字体,因为不能确保闭包不会被多次调用(实际上,它被多次调用)。

这是不正确的。它不在乎font是在闭包之前创建的,因为它是在之后移动闭包中的。同样多次调用闭包,没关系,字体现在属于闭包。

闭包是具有关联函数的结构,作为环境一部分的所有变量实际上都设置为结构的成员,在调用函数时可以从中提取它们以填充自由变量。就是这样。在闭包之外创建项目(否则您将如何关闭它们?)或多次调用闭包没有具体问题。

let font = Font;
let t: u8 = (0..5).map(move |_| Font::thing(&font)).sum();

错误的意思是,在闭包内你正在借用一些东西,而你正试图将那个借用移到闭包之外。

于 2020-05-25T10:45:43.170 回答