1

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?

programandoconro
  • 2,378
  • 2
  • 18
  • 33

1 Answers1

3

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)
}
Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77