Rust中Church数转usize函数问题:计数器未更新
问题分析与解决
你的counter和counter_clone引用是完全正确的,它们共享同一个RefCell实例,不存在引用问题。计数器始终为0的根本原因是传入的Church数没有正确实现“将函数f应用n次”的逻辑,导致你传入的计数闭包从未被执行。
正确的Church数实现示例
要让to_usize正常工作,你需要先正确定义Church数的基础实现:
use std::rc::Rc; pub type Church<T> = Rc<dyn Fn(Rc<dyn Fn(T) -> T>) -> Rc<dyn Fn(T) -> T>>; // Church数0:不执行传入的函数,直接返回输入值 pub fn zero<T>() -> Church<T> { Rc::new(|_f| Rc::new(|x| x)) } // 后继函数:将给定Church数n转换为n+1 pub fn succ<T>(n: Church<T>) -> Church<T> { Rc::new(move |f| { let n_applied = n(Rc::clone(&f)); Rc::new(move |x| f(n_applied(x))) }) } // 示例:创建Church数1 pub fn one<T>() -> Church<T> { succ(zero()) } // 示例:创建Church数2 pub fn two<T>() -> Church<T> { succ(one()) }
验证to_usize函数
使用上面的Church数实现,调用to_usize(one::<i32>())会返回1,to_usize(two::<String>())会返回2,计数器会正确更新。
优化to_usize实现
你可以用Cell替代RefCell简化代码(因为计数器是usize,属于Copy类型,Cell的操作更轻便):
use std::cell::Cell; pub fn to_usize<T: 'static + Default>(n: Church<T>) -> usize { let counter = Rc::new(Cell::new(0)); let counter_clone = Rc::clone(&counter); let f = Rc::new(move |_x: T| { counter_clone.set(counter_clone.get() + 1); Default::default() }); let result_func = n(f); let _ = result_func(Default::default()); counter.get() }
内容的提问来源于stack exchange,提问作者안태찬
相关产品推荐
相关产品推荐

