如何在 gtk-rs 闭包中设置变量?
How to set a variable inside a gtk-rs closure?
我正在构建一个降价应用程序,我想保留两份文本,一份是 source
文本,另一份是 TextBuffer
以及所有正确的标签等。
我需要在闭包中设置此源字段的内容:
buffer.connect_begin_user_action(clone!(source => move |a| {
let text = a.get_text(&a.get_start_iter(), &a.get_end_iter(), false).unwrap();
source = text; // error: cannot assign to captured outer variable in an `Fn` closure
另一种方法可能是在 TextBuffer
上设置一些属性,但我不知道这是否可行。
TextBufferExt::connect_begin_user_action()
接受 Fn
-闭包,即不能改变其捕获环境的闭包。当您需要更改无法更改的内容时,可以使用具有内部可变性的类型,例如 RefCell
.
如果将 source
的类型调整为 RefCell<String>
并将闭包内的赋值更改为 *source.borrow_mut() = text;
,代码将编译,但还有另一个问题。您为克隆的 source
赋值。
宏clone!
扩展为
{
let source = source.clone();
move |a| {
let text = // ...
// ...
}
}
也就是说,闭包捕获并更改了变量source
的副本,而不是原始变量。 Rc
是实现您预期目的的方法之一
use std::cell::RefCell;
use std::rc::Rc;
// ...
let source = Rc::new(RefCell::new("Text".to_string()));
// ...
buffer.connect_begin_user_action(clone!(source => move |a| {
let text = a.get_text(&a.get_start_iter(), &a.get_end_iter(), false).unwrap();
*source.borrow_mut() = text;
// ...
}));
另一种方法是删除 clone!
宏并通过引用捕获 source
(您需要在关闭前删除 move
),但在这种情况下它不会像 connect_begin_user_action()
期望一个生命周期为 'static
的闭包,即没有捕获局部变量引用的闭包。
我正在构建一个降价应用程序,我想保留两份文本,一份是 source
文本,另一份是 TextBuffer
以及所有正确的标签等。
我需要在闭包中设置此源字段的内容:
buffer.connect_begin_user_action(clone!(source => move |a| {
let text = a.get_text(&a.get_start_iter(), &a.get_end_iter(), false).unwrap();
source = text; // error: cannot assign to captured outer variable in an `Fn` closure
另一种方法可能是在 TextBuffer
上设置一些属性,但我不知道这是否可行。
TextBufferExt::connect_begin_user_action()
接受 Fn
-闭包,即不能改变其捕获环境的闭包。当您需要更改无法更改的内容时,可以使用具有内部可变性的类型,例如 RefCell
.
如果将 source
的类型调整为 RefCell<String>
并将闭包内的赋值更改为 *source.borrow_mut() = text;
,代码将编译,但还有另一个问题。您为克隆的 source
赋值。
宏clone!
扩展为
{
let source = source.clone();
move |a| {
let text = // ...
// ...
}
}
也就是说,闭包捕获并更改了变量source
的副本,而不是原始变量。 Rc
是实现您预期目的的方法之一
use std::cell::RefCell;
use std::rc::Rc;
// ...
let source = Rc::new(RefCell::new("Text".to_string()));
// ...
buffer.connect_begin_user_action(clone!(source => move |a| {
let text = a.get_text(&a.get_start_iter(), &a.get_end_iter(), false).unwrap();
*source.borrow_mut() = text;
// ...
}));
另一种方法是删除 clone!
宏并通过引用捕获 source
(您需要在关闭前删除 move
),但在这种情况下它不会像 connect_begin_user_action()
期望一个生命周期为 'static
的闭包,即没有捕获局部变量引用的闭包。