2017-08-15 30 views
0

私はマークダウンアプリを構築していますが、テキストのコピーを2つ、つまりのテキストと、すべて正しいタグなどのTextBufferのテキストを保持したいとします。gtk-rsクロージャ内で変数を設定するには?

私はクロージャ内でこのソースフィールドの内容を設定する必要があります。

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上のいくつかの属性を設定するかもしれないが、これが可能であるかどうかはわかりません。

+1

なぜこのライブラリを使用すると、残りの言語のセマンティクスとルールが変更されると思いますか?言い換えれば、なぜあなたはgtk-rsが使用されていることが重要だと思いますか?これは、「錆止めの内側に変数を設定する方法」という仮説的な質問の複製として閉じられるでしょうか? – Shepmaster

+0

質問の名前を変更するかどうかわかりません。 – thouliha

答えて

1

TextBufferExt::connect_begin_user_action()は、Fn -closuresを受け入れます。つまり、キャプチャされた環境を変更できないクロージャです。変更できないものを変更する必要がある場合は、RefCellのような内部の変更可能な型を使用できます。

のタイプをRefCell<String>に調整し、クロージャ内の割り当てを*source.borrow_mut() = text;に変更すると、コードはコンパイルされますが、別の問題があります。クローン化されたsourceに値を割り当てます。

マクロclone!は、閉鎖捕捉され、可変sourceではなく、元の変数のコピーを変更

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

に展開します。 Rcはあなたが別の方法は、マクロclone!を削除し、参照することによりsourceをキャプチャ(あなたが閉鎖する前moveを削除する必要があります)が、この場合には、それはとして動作しませんされて

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

意図何をすべきかのいずれかの方法でありますconnect_begin_user_action()は、生涯の'staticのクロージャーを必要とします。これは、ローカル変数への参照がキャプチャされていないクロージャーです。

+0

ありがとう、これでした! – thouliha

関連する問題