You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,提问作者안태찬

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 05:04:52