如何更改闭包中的值并将其打印在另一个闭包中?生锈-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>>
。
在尝试编写一个基本的 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>>
。