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

如何用闭包在Rust中实现Landin's Knot?

Landin's Knot:无需函数名的自引用递归技巧

Landin's Knot是一种无需引用函数自身名称即可实现递归的技巧,适用于原生不支持递归的编程语言。

伪代码中,我们可以按如下方式创建能递归调用自身的函数f:

let id = (x) => x    // 创建临时函数
let r = id           // 将函数存入引用
let f = (n) => !r(n) // 创建函数f,它会解引用并调用r指向的函数
r = f                // 把r重新指向f
f(0)                 // 此时f已能实现递归

注:上述示例会无限循环/导致栈溢出,只需简单调整f的定义,就能添加基准情况或用来计算斐波那契数列等。

我尝试了以下朴素的Rust实现,但因编译错误无法运行:

trait I32Fn {
    fn call(&mut self, x: i32) -> i32;
}

struct Closure {
    f: Box<dyn FnMut(i32) -> i32>,
}

impl I32Fn for Closure {
    fn call(&mut self, x: i32) -> i32 {
        (self.f)(x)
    }
}

fn main() {
    let id: Box<dyn I32Fn> = Box::new(Closure { f: Box::new(|x| x) });
    let mut r = id;
    let mut f: Box<dyn I32Fn> = Box::new(Closure {
        f: Box::new(|n: i32| -> i32 { (*r).call(n) }),
    });
    *r = *f;
    println!("{}", (*f).call(0));
}

如果我们将闭包有序存储在堆上(比如使用内存池),是否存在安全实现闭包自引用的方法?


内容的提问来源于stack exchange,提问作者Christopher Rybicki

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 14:15:05