2017-08-15 5 views
0

Ich baue eine Abschriften-App, und ich möchte zwei Kopien des Textes, eine source Text, und die andere die TextBuffer mit allen richtigen Tags und so.Wie setze ich eine Variable innerhalb eines gtk-rs-Abschlusses?

Ich brauche in einem Verschluss, den Inhalt dieses Quellfeldes zu setzen:

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 

Eine Alternative könnte einige Attribute auf den TextBuffer gesetzt sein, aber ich weiß nicht, ob dies möglich ist.

+1

Warum glauben Sie, dass die Verwendung dieser Bibliothek die Semantik und Regeln des Rests der Sprache verändern wird? Anders gesagt, warum ist es wichtig, dass gtk-rs verwendet wird? Könnte dies als ein Duplikat einer hypothetischen Frage geschlossen werden, die lautet "Wie setze ich eine Variable innerhalb einer Rust-Schließung?" – Shepmaster

+0

Ich bin mir nicht sicher, wo ich die Frage umbenennen soll. – thouliha

Antwort

1

TextBufferExt::connect_begin_user_action() akzeptiert Fn -Verschlüsse, das sind Verschlüsse, die ihre erfasste Umgebung nicht ändern können. Wenn Sie etwas ändern müssen, das nicht geändert werden kann, können Sie Typen mit interner Änderbarkeit verwenden, z. B. RefCell.

Wenn Sie die Art des source-RefCell<String> anpassen und Zuordnung zu *source.borrow_mut() = text; innerhalb Schließung ändern, wird der Code kompilieren, aber es ist ein anderes Problem. Sie weisen dem geklonten source einen Wert zu.

Das Makro clone! expandiert in

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

Das heißt, die Schließung erfasst und ändert eine Kopie der Variablen source, nicht die ursprüngliche Variable. Rc ist eine der Methoden, zu tun, was Sie

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

Ein anderes Verfahren durch Verweis clone! Makro- und Erfassung source sollten entfernen (Sie werden move vor Schließung entfernen müssen), aber in diesem Fall wird es nicht funktionieren wie connect_begin_user_action() erwartet eine Schließung mit 'static Lebensdauer, das ist eine Schließung ohne erfasste Verweise auf lokale Variablen.

+0

Vielen Dank, das war es! – thouliha

Verwandte Themen