Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Creating a Rust useState-like function to get and set state using closures

I am trying to implement a useState-like function in Rust. I mean, a function that takes a value and returns its state as well as a function to modify it. I know that this is possible using setter and getter in something like OO for Rust(example). But, I am trying to do it using closures inside a function. How can I achieve this?

This is my try:

fn use_state<T: Copy>(value: T) -> (impl Fn() -> T, impl FnMut(T)) {
    let mut val: T = value;

    let state = move || -> T { val };

    let set_state = move |v: T| {
        val = v;
    };
    (state, set_state)
}

fn main() {
    let (counter, mut set_counter) = use_state(0);
    println!("{:?}", counter()); // 0

    set_counter(1);
    println!("{:?}", counter()); // 0 but I expected 1

}

I managed to do this in Typescript(here), but I do not know how to implement it in Rust. What am I missing?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

You copy the value to each closure, meaning they don’t share it. When one will change its value, the other won’t be affected.

You need to use reference counting to share the value, with interior mutability to change the value behind:

use std::rc::Rc;
use std::cell::Cell;

fn use_state<T: Copy>(value: T) -> (impl Fn() -> T, impl FnMut(T)) {
    let val = Rc::new(Cell::new(value));

    let state = {
        let val = Rc::clone(&val);
        move || -> T { val.get() }
    };

    let set_state = move |v: T| {
        val.set(v);
    };
    (state, set_state)
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading