创建一个Rust类usestate函数,使用闭包获取和设置状态



我正在尝试在Rust中实现一个类似usestate的函数。我的意思是,一个接受一个值并返回它的状态的函数以及一个修改它的函数。我知道这是可能的使用setter和getter在像面向对象的Rust(示例)。但是,我试图在函数内使用闭包来做到这一点。我怎样才能做到这一点呢?

这是我的尝试:

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
}

我设法在Typescript中做到这一点(这里),但我不知道如何在Rust中实现它。我错过了什么?

将值复制到每个闭包中,这意味着它们不共享该值。当其中一个改变其值时,另一个不受影响。

你需要使用引用计数来共享值,使用内部可变性来改变后面的值:

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)
}