gpt4 book ai didi

rust - 如何在rust的GTK事件中设置结构的值?

转载 作者:行者123 更新时间:2023-12-03 11:36:38 25 4
gpt4 key购买 nike

如何在rust的GTK事件中设置结构的值?
尝试修改下面的s结构实例时,出现错误。

use gtk::prelude::*;
use gio::prelude::*;

use gtk::{Application, ApplicationWindow, Button};

struct SomeStruct {
val: bool,
}

fn main() {
let mut s = SomeStruct {
val: false,
};

application.connect_activate(|app| {
let window = ApplicationWindow::new(app);
window.set_title("test");
window.set_default_size(350,70);

let button = Button::with_label("Test");



button.connect_clicked(|_|{
s.val = true; // error here
});

window.add(&button);
window.show_all();
});

application.run(&[]);
}

错误消息:
error[E0597]: `s` does not live long enough

error[E0596]: cannot borrow `s` as mutable, as it is a captured variable in a `Fn` closure

最佳答案

您的代码有两个问题:

  • 尽管s不在GTK应用程序中,但Rust并不知道,这就是为什么它提示s生命周期不够长的原因。
  • ButtonExt::connect_clicked() 接受Fn,因此,如果没有额外的预防措施,则不允许对数据进行变异。

  • 可以通过在堆上分配 s并通过 reference-counted pointer访问它来解决第一个问题,这可以确保对象的生存时间至少与引用它的闭包一样长。
    通过将 SomeStruct包装到 RefCell 中,第二个问题最容易通过内部可变性解决。 RefCell保留一个值,并允许持有者通过对 RefCell的共享引用对其进行突变。当请求对内部值的 mut引用时, RefCell将在运行时检查是否没有其他对该值的引用仍然有效。 (如果您的闭包要访问该值,然后在保持该值的同时调用另一个执行相同操作的闭包,则可能会发生这种情况。)
    两者结合起来将导致这样的代码(未经测试):
    use std::rc::Rc;
    use std::cell::RefCell;

    fn main() {
    let s = Rc::new(RefCell::new(SomeStruct { val: false }));

    application.connect_activate(|app| {
    let window = ApplicationWindow::new(app);
    window.set_title("test");
    window.set_default_size(350, 70);

    let button = Button::with_label("Test");

    // clone the handle to s and move it into the closure
    let s2 = Rc::clone(&s);
    button.connect_clicked(move |_| {
    s2.borrow_mut().val = true;
    });

    window.add(&button);
    window.show_all();
    });

    application.run(&[]);
    }

    关于rust - 如何在rust的GTK事件中设置结构的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65049374/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com