我正在使用 rdev 库来获取用户的键盘输入。我创建了一个名为 InputManager 的类,它有一个像这样的监听方法
use rdev;
struct InputManager {}
impl InputManager {
pub fn new() -> Self {
InputManager {}
}
fn callback(&mut self, event: rdev::Event) {
println!("My callback {:?}", event);
match event.name {
Some(string) => println!("User wrote {:?}", string),
None => (),
}
}
pub fn listen(&mut self) -> Result<(), ()> {
match rdev::listen(|event: rdev::Event| self.callback(event)) {
Ok(_) => Ok(()),
Err(_) => Err(()),
};
Ok(())
}
}
fn main() {
let mut input_manager = InputManager::new();
input_manager.listen();
}
这会产生以下错误,因为
rdev::listen
函数需要静态回调
--> src/main.rs:19:15
|
18 | pub fn listen(&mut self) -> Result<(), ()> {
| ---------
| |
| `self` is a reference that is only valid in the method body
| let's call the lifetime of this reference `'1`
19 | match rdev::listen(|event: rdev::Event| self.callback(event)) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| `self` escapes the method body here
| argument requires that `'1` must outlive `'static`
如何解决这个问题,同时将回调方法保留在类中?
listen()
的闭包必须是'static
,但你的闭包是借用self
来调用self.callback()
,而pub fn listen(&mut self) -> ...
只给你一个更短的临时借用比'static
。换句话说,当 listen()
调用闭包时,&self
可能已经无效,因此编译器会拒绝该程序。
答案取决于您想要做什么:您可以将您的方法变成
pub fn listen(self)
(取得所有权)。这将允许 self
移动到闭包中,并且闭包变为 'static
(因为它不包含任何比 'static
短的内容)。缺点是您的 listen()
只能被调用一次,因为需要拥有 InputManager
的所有权才能将该所有权传递给 listen()
。self
包装成 Rc
(例如 pub fn listen(self: Rc<Self>)
),这也允许 self
作为 'static
值传递。
鉴于
rdev::listen()
似乎是一个全局事件循环,我建议选择第一个选项,并将pub fn listen(&mut self)
更改为pub fn listen(self)
。