How to set a variable inside a gtk-rs closure?

本秂侑毒 提交于 2020-01-30 11:16:10

问题


I'm building a markdown app, and I want to keep two copies of the text, one a source text, and the other the TextBuffer with all the correct tags and such.

I need to set the contents of this source field inside a closure:

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

An alternative might be to set some attribute on the TextBuffer, but I don't know if this is possible.


回答1:


TextBufferExt::connect_begin_user_action() accepts Fn-closures, that is closures which can't change their captured environment. When you need to change something that can't be changed, you can use types with interior mutability, like RefCell.

If you'll adjust the type of source to RefCell<String> and change assignment inside closure to *source.borrow_mut() = text;, the code will compile, but there's another problem. You assign a value to the cloned source.

The macro clone! expands into

{
    let source = source.clone();
    move |a| {
       let text = // ...
       // ...
    }
}

That is, the closure captures and changes a copy of the variable source, not the original variable. Rc is one of the methods to do what you intended

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;
    // ...
}));

Another method is removing clone! macro and capturing source by reference (you'll need to remove move before closure), but in this case it will not work as connect_begin_user_action() expects a closure with 'static lifetime, that is a closure with no captured references to local variables.



来源:https://stackoverflow.com/questions/45702112/how-to-set-a-variable-inside-a-gtk-rs-closure

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!