如何用闭包在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
相关产品推荐
相关产品推荐

