如何更改闭包中的值并将其打印在另一个闭包中?生锈-gtk

How to change a value in a closure and print it in another? Rust - gtk

在尝试编写一个基本的 Rust gtk 应用程序时,我一直无法检索值并从条目中打印出来。它归结为无法更改然后显示两个不同闭包中的值,与两个不同的信号相关联。

一些搜索让我找到了 RefCell 似乎需要做这样的事情,但我仍然没有成功。

我想要实现的目标看起来像这样:

    let mut x: i32 = 0;

    btn.connect_clicked(clone!(@weak lbl => move |_|{
        lbl.set_text("btn1 clicked");
        x = 1;
    }));

    btn2.connect_clicked(clone!(@weak lbl => move |_|{
        lbl.set_text("btn2 clicked");
        println!("stored value of x is {}", x);
    }));

据我所知,我无法在第一个闭包中为 x 分配新值,因为这是一个 Fn,但正确的方法是什么?

首先,您需要将变量包装在 Rc<T> 中。它是一种共享指针类型,它使用引用计数来决定何时取消分配对象。您需要它,因为您必须保证只要您的应用程序的某些组件仍然持有该对象,该对象的引用就会一直有效。

正如您已经发现的,您还需要使用 interior mutability 模式来更改值,因为 Rc 不允许更改。

所以最后你应该有:

let x = Rc::new(RefCell::new(0));

现在您应该克隆 Rc 并在闭包中使用克隆:

let x1 = Rc::clone(x);
btn.connect_clicked(clone!(@weak lbl => move |_|{
    lbl.set_text("btn1 clicked");
    *x1.borrow_mut() = 1;
}));

let x2 = Rc::clone(x);
btn2.connect_clicked(clone!(@weak lbl => move |_|{
    lbl.set_text("btn2 clicked");
    println!("stored value of x is {}", x2.borrow());
}));

只要您不尝试将 Rc 发送到另一个线程并同时改变值,这应该可以工作。对于多线程内部可变性,您应该改用 Arc<Mutex<T>>