12345654321
12345654321

Reputation: 3

How use Rc Refcell in rust (and stdweb)

i have a litle problem with this code:

I have two closure and I want the variable counter to be used in both of them.

fn main() {
    stdweb::initialize();


    let counter_div = document().query_selector(DIV_SELECTOR_NAME).unwrap().unwrap();
    // create Rc RefCell struct here 
    let mut counter = Rc::new(RefCell::new(ClickCounter::new()));

    counter_div.clone().add_event_listener(move |_: MouseDownEvent| {
        // ERROR move How make this work?
        counter.clone().borrow_mut().increment();
    });


    let upgrade_div = document().query_selector(UPGRADE_DIV_SELECTOR_NAME).unwrap().unwrap();
    upgrade_div.clone().add_event_listener( move |_: MouseDownEvent|{

       // ERROR move! 
       counter.clone().borrow_mut().upgrade_click(upgrade);
    });


    stdweb::event_loop();
}

Upvotes: 0

Views: 828

Answers (1)

Freyja
Freyja

Reputation: 40924

When using Rc with move closures, you need to clone first, and then move the variable into the closure. With the code you've written, you're first cloning the variable after it has been moved into the closure, meaning that it is not available when the second closure tries to do the same.

An example:

let counter = Rc::new(RefCell::new(ClickCounter::new()));

{
    // Clone into a new variable outside of the closure.
    let cloned_counter = counter.clone();

    counter_div.add_event_listener(move |_: MouseDownEvent| {
        // Note: We're no longer cloning here.
        cloned_counter.borrow_mut().increment();
    });
}

// ...

{
    // Clone the counter variable on line 1 again.
    let cloned_counter = counter.clone();
    upgrade_div.add_event_listener(move |_: MouseDownEvent| {
        cloned_counter.borrow_mut().upgrade_click(upgrade);
    });
}

Upvotes: 2

Related Questions