Rust 将可变上下文传递到回调中
我正在尝试用Rust构建一个简单的UI,但在Lua中可以部分编写脚本,使用Rust-lua53,并且在找到一种让Lua组件访问Lua状态的好方法时遇到了问题。这个问题/例子比我想的要长一点,对不起 UI的核心是一个Rust 将可变上下文传递到回调中,rust,lifetime,Rust,Lifetime,我正在尝试用Rust构建一个简单的UI,但在Lua中可以部分编写脚本,使用Rust-lua53,并且在找到一种让Lua组件访问Lua状态的好方法时遇到了问题。这个问题/例子比我想的要长一点,对不起 UI的核心是一个小部件特性,当按键或屏幕/窗口应该重画时,可以调用这些方法。类型参数C是我要传递的上下文(见下文) 您可以通过实现Widget并调用ui.run(Widget)来使用它,它运行一个事件循环,直到它“完成”(比如在Widget上按下一个按钮),并将控件返回给调用者 Lua状态有一个包装器
小部件
特性,当按键或屏幕/窗口应该重画时,可以调用这些方法。类型参数C
是我要传递的上下文(见下文)
您可以通过实现Widget
并调用ui.run(Widget)
来使用它,它运行一个事件循环,直到它“完成”(比如在Widget上按下一个按钮),并将控件返回给调用者
Lua状态有一个包装器,它(除其他外)处理安全地获取指针以使对象生锈:
struct RL<'a> {
marker: PhantomData<(&'a ())>,
}
impl<'a> RL<'a> {
pub fn get<T>(&mut self) -> Option<Ptr<T>>
where T: Any
{ unimplemented!() }
pub fn register(&mut self, func: (&'static str, fn(&mut RL) -> ()))
{ unimplemented!() }
}
最后,需要注册l_run方法:
fn main() {
let mut rl = RL{marker: PhantomData};
rl.register(("l_run", MyWidget::l_run));
}
当前尝试的结果是:
错误:由于需求冲突,无法推断适当的生存期[E0495]
--> :57:35
|>
57 |>设mut-ctxt:MyContext=MyContext{rl:rl,};
|> ^^^^^^^^^
帮助:考虑使用显式生命周期参数,如图所示:FN LyRun:7:27
|>
74 |>rl.register((“l|u run”,MyWidget::l|u run));
|>^^^^^^^^^^^^^^^^^^^^^^^^^^预期的混凝土寿命,找到绑定的寿命参数
注意:预期类型`fn(&mut RL这些深层生存期问题很棘手,因此让我们看看是否能够解决它。让我们先看看具有相同错误的精简版本代码:
struct RunLoop<'a> {
marker: &'a u8,
}
struct MyContext<'a> {
rl: &'a mut RunLoop<'a>,
}
fn run(rl: &mut RunLoop) {
let mut ctxt = MyContext { rl: rl };
}
fn main() {}
struct RunLoop<'a> {
marker: &'a u8,
}
struct MyContext<'a> {
rl: &'a mut RunLoop<'a>,
}
fn run<'a>(rl: &'a mut RunLoop<'a>) {
let mut ctxt = MyContext { rl: rl };
}
fn register(func: fn(&mut RunLoop)) {}
fn main() {
register(run);
}
另一个解决方案是编译器暗示的:在调用run
时预先统一生存期:
fn run<'a>(rl: &'a mut RunLoop<'a>) {
这一点我不太确定。我确实知道,在引用上放置任何显式生存期都有助于它编译:
fn register<'a>(func: fn(&'a mut RunLoop<'a>)) {}
fn register<'a, 'b>(func: fn(&'a mut RunLoop<'b>)) {}
fn register(func: fn(&'static mut RunLoop)) {}
fn register这似乎是示例构建,谢谢,但不是真正的代码。我想我需要找出不同之处。我已经编辑添加了缺少的部分(注册函数)这在实际应用程序中会停止工作。您的链接会转到localhost…当然,表现为您无法访问Internet上最流行的网页。(请注意,gist
参数在两个操场上都有效,我只是在我的操场上做一些本地工作)。
error: mismatched types [--explain E0308]
--> <anon>:74:27
|>
74 |> rl.register(("l_run", MyWidget::l_run));
|> ^^^^^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter
note: expected type `fn(&mut RL<'_>)`
note: found type `fn(&'r mut RL<'r>) {MyWidget::l_run}`
note: expected concrete lifetime is lifetime ReSkolemized(0, BrAnon(0))
struct RunLoop<'a> {
marker: &'a u8,
}
struct MyContext<'a> {
rl: &'a mut RunLoop<'a>,
}
fn run(rl: &mut RunLoop) {
let mut ctxt = MyContext { rl: rl };
}
fn main() {}
struct MyContext<'a, 'b : 'a> {
rl: &'a mut RunLoop<'b>,
}
fn run<'a>(rl: &'a mut RunLoop<'a>) {
struct RunLoop<'a> {
marker: &'a u8,
}
struct MyContext<'a> {
rl: &'a mut RunLoop<'a>,
}
fn run<'a>(rl: &'a mut RunLoop<'a>) {
let mut ctxt = MyContext { rl: rl };
}
fn register(func: fn(&mut RunLoop)) {}
fn main() {
register(run);
}
fn register<'a>(func: fn(&'a mut RunLoop<'a>)) {}
fn register<'a, 'b>(func: fn(&'a mut RunLoop<'b>)) {}
fn register(func: fn(&'static mut RunLoop)) {}