Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 将可变上下文传递到回调中_Rust_Lifetime - Fatal编程技术网

Rust 将可变上下文传递到回调中

Rust 将可变上下文传递到回调中,rust,lifetime,Rust,Lifetime,我正在尝试用Rust构建一个简单的UI,但在Lua中可以部分编写脚本,使用Rust-lua53,并且在找到一种让Lua组件访问Lua状态的好方法时遇到了问题。这个问题/例子比我想的要长一点,对不起 UI的核心是一个小部件特性,当按键或屏幕/窗口应该重画时,可以调用这些方法。类型参数C是我要传递的上下文(见下文) 您可以通过实现Widget并调用ui.run(Widget)来使用它,它运行一个事件循环,直到它“完成”(比如在Widget上按下一个按钮),并将控件返回给调用者 Lua状态有一个包装器

我正在尝试用Rust构建一个简单的UI,但在Lua中可以部分编写脚本,使用Rust-lua53,并且在找到一种让Lua组件访问Lua状态的好方法时遇到了问题。这个问题/例子比我想的要长一点,对不起

UI的核心是一个
小部件
特性,当按键或屏幕/窗口应该重画时,可以调用这些方法。类型参数
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)) {}