使用部分移动的值:闭包中的“self”

use of partially moved value: `self` in closure

提问人:Thomas 提问时间:10/8/2023 更新时间:10/9/2023 访问量:78

问:

我在 rust 中有一个结构:

pub struct Application {
    name: String,
    windows: Vec<Window>,
    event_loop: EventLoop<()>,
}

在这里,我有一个移动自我并运行一个事件循环的方法,该循环采用移动闭包。我仍然想引用 self,因为它有一些我需要根据事件运行的方法。它看起来像这样

    pub fn run(mut self) {
        self.event_loop.run(move |event, _, control_flow| match event {
            Event::WindowEvent {
                window_id,
                ..
            } => {
                &self.send_event_to_window(window_id, event);
            },
            Event::RedrawRequested(window_id) => {
                &self.send_event_to_window(window_id, event);
            }
            Event::MainEventsCleared => {
                // RedrawRequested will only trigger once, unless we manually
                // request it.
                // state.window().request_redraw();
            }
            _ => {},
        });
    }

Rust 对我使用 self.send_event_to_window 有问题,并说 “使用部分移动的值:self"

我如何从这个闭包中访问自我?我什至不确定为什么 rust 不允许我在将其移入闭合时使用它。

Rust Closures 借用检查器

评论

0赞 Peter Hall 10/8/2023
“我甚至不确定为什么生锈不允许我在将它移入封盖时使用它。”-- 您已移入闭包,这意味着除了闭包之外,它不能再在任何地方使用。但随后你呼吁它。selfrun
0赞 Peter Hall 10/8/2023
是什么促使你在这里使用这个关键词?move
0赞 Peter Hall 10/8/2023
假设您正在使用 ,请看一下示例。它们都不是按照您的代码构建方式的。例如,github.com/rust-windowing/winit/blob/master/examples/...winit
0赞 Thomas 10/8/2023
You moved self into the closure, which means it can no longer be used anywhere except in the closure.是的,但我试图在闭包调用中使用它&self.send_event_to_window
0赞 Peter Hall 10/8/2023
为什么要将应用程序的字段设置为结构?问问自己是否有必要。看看这些想法的例子。event_loopwinit

答:

1赞 Max Meijer 10/9/2023 #1

当你写进去时,则拥有 的所有权(部分所有权)。因此,闭包不能调用任何方法,因为这样的方法可能会使用 。self.eventLoop.runApplication.runEventLoop.runself.eventLoopselfselfself.eventLoop

有几种方法可以解决此问题:

  1. 在函数中创建一个局部变量event_looprun
  2. 创建函数的参数event_looprun
  3. 将所需的变量放入单独的结构中,如下所示:event_loop
pub struct ApplicationState {
  name: String,
  windows: Vec<Window>,
  // put anything that needs to be accessible by the run closure here
}
impl ApplicationState {
 // implement functions that do not use event_loop here
 // these can be called by the run closure
 fn send_event_to_window(window_id, event) {}
}
pub struct Application {
  state: ApplicationState,
  event_loop: EventLoop<()>,
}
impl Application {
      pub fn run(mut self) {
        self.event_loop.run(move |event, _, control_flow| match event {
            Event::WindowEvent {
                window_id,
                ..
            } => {
                &self.state.send_event_to_window(window_id, event);
            },
            Event::RedrawRequested(window_id) => {
                &self.state.send_event_to_window(window_id, event);
            }
            Event::MainEventsCleared => {
                // RedrawRequested will only trigger once, unless we manually
                // request it.
                // state.window().request_redraw();
            }
            _ => {},
        });
    }
}