rust - 返回一个将环境可变变量从函数移入其中的递归闭包?

标签 rust

从问题的公认答案来看,递归关闭的方式不适合我:

Is it possible to make a recursive closure in Rust?

我的闭包需要从函数返回,需要将变量从环境中移入其中,并可以改变它。

然后我发现一个方法似乎更适合我:

Anonymous recursion with closures

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));        
}

上面的代码工作正常。

但是我的闭包需要从一个函数中返回,所以它不能是一个引用来防止悬空引用,而且我们在编译时不知道闭包的大小,所以我使用了智能指针 Box 为它。以下代码会引发错误:

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));        
}
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

最佳答案

您可以将递归上下文包装在非递归闭包中:

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)
    })
}

关于rust - 返回一个将环境可变变量从函数移入其中的递归闭包?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52602808/

相关文章:

rust - 如何在 Diesel 中为自定义字段类型实现可查询和可插入?

rust - 如何引用特征并仍然使用原始结构?

multithreading - 如何在 Rust 中访问外部线程局部全局变量?

types - rustc 奇怪地假设类型参数必须相同,即使它们是分开的?

rust - 使用 petgraph 随机游走

rust - 如何同时获取对两个数组元素的可变引用?

asynchronous - Rust 显示预期的特征对象 `dyn Future` ,在将函数作为参数传递时发现不透明类型

unix - 可以将mut i8转换为i32吗?

rust - 如何在 Rust 中将 bson::Bson 转换为 Vec<u8> ?

rust - 是否有保留插入顺序的集合类型?