button.connect_clicked(move |_|
{
let value = Rc::clone(&value);
let mut counter = value.lock().unwrap();
*counter += 1;
});
Then outside of the callback I have this:
{
let widget_box = gtk::Box::new(Orientation::Vertical, 1);
let value = Rc::clone(&value);
let counter = value.lock().unwrap();
let label = Label::new(Some(&format!("No of Jobs: {}", counter)));
widget_box.add(&label);
mainbox.add(&widget_box);
}
and I get this error:
value borrowed here after move
Whilst I can clone the variable outside of the closure but is there another alternative without having to create another variable and clone the main variable outside the closure?
this is the correct way to share resouces using Rc. I don't know why you want to avoid that?
a move closure captures variables by value, making a clone inside the closure is meaningless because the original value is already moved into (i.e. owned by) the closure, it cannot be accessed outside the closure any more.
to fine control the capture of a move closure, you can use a block expression:
let value = Rc::new(...);
button.connect_clicked({
let value = Rc::clone(&value);
move |_| {
...
}
});
btw, it makes no sense to use Rc with Mutex, Rc is single threaded, you don't need Mutex in single threaded context: a RefCell is better, since it has lower overhead than Mutex. but it is even better to use Cell in this particular example, which has zero overhead, since the shared data is just u8.
here's the code using Rc<Cell<u8>>:
let value = Rc::new(Cell::new(0u8));
button.connect_clicked({
let value = Rc::clone(&value);
move |_| {
// access `value` inside the closure
value.set(value.get() + 1);
}
});
// access `value` outside the closure
//...
let counter = value.get();
let label = Label::new(Some(&format!("No of Jobs: {}", counter)));
//...
you want two owners of the shared value, you use two variables.
Cell is only useful for types that is Copy, this includes all the integer types, floating point types, raw pointers, shared references, etc. for other non-Copy types, use RefCell instead.
gtk::Entry is non-Copy, so you should use RefCell.
A strong reference is just an Rc, which will be produced by cloneing the given Rc, while a weak reference is a std::rc::Weak which is created by calling Rc::downgrade. Weak references are useful for avoiding strong references cycles, which will result in a memory leak.