return a recursive closure which move environmental mutable variable into it from a function?
从问题的可接受答案来看,进行递归关闭的方式不适合我:
是否可以在Rust中进行递归关闭?
我的闭包需要从一个函数返回,并且需要将变量从环境移入它,并且可以对其进行变异。
然后我发现一种方法似乎更适合我:
带闭包的匿名递归
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | use std::cell::RefCell; fn main() { let id = &(|a| a) as &Fn(u64) -> u64; let (fib, fib_p): (_, RefCell<&Fn(u64) -> u64>); fib_p = RefCell::new(id); fib = |n: u64| { if n < 2 { n } else { (fib_p.borrow())(n - 2) + (fib_p.borrow())(n - 1) } }; *fib_p.borrow_mut() = &fib; println!("{}", fib(10)); } |
上面的代码可以正常工作。
但是我的闭包需要从函数中返回,因此它不能用作防止悬挂的Reference的引用,并且我们从编译时就不知道闭包的大小,因此我使用了智能指针
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | use std::cell::RefCell; fn main() { let id: Box<Fn(u64) -> u64> = Box::new(|a| a); let (fib, fib_p): (Box<Fn(u64) -> u64>, RefCell<&Box<Fn(u64) -> u64>>); fib_p = RefCell::new(&id); fib = Box::new(|n: u64| { if n < 2 { n } else { (fib_p.borrow())(n - 2) + (fib_p.borrow())(n - 1) } }); *fib_p.borrow_mut() = &fib; println!("{}", fib(10)); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 | error[E0597]: `fib_p` does not live long enough --> src/main.rs:12:15 | 8 | fib = Box::new(|n: u64| { | -------- capture occurs here ... 12 | (&fib_p.borrow())(n - 2) + (&fib_p.borrow())(n - 1) | ^^^^^ borrowed value does not live long enough ... 19 | } | - borrowed value dropped before borrower | = note: values in a scope are dropped in the opposite order they are created |
您可以将递归上下文package在非递归闭包中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | pub fn fib() -> Box<Fn(u64) -> u64> { Box::new(|n: u64| { let id = &(|a| a) as &Fn(u64) -> u64; let (fib, fib_p): (_, RefCell<&Fn(u64) -> u64>); fib_p = RefCell::new(id); fib = |n: u64| { if n < 2 { n } else { (fib_p.borrow())(n - 2) + (fib_p.borrow())(n - 1) } }; *fib_p.borrow_mut() = &fib; fib(n) }) } |