首页 > 解决方案 > 如何递归调用存储在 Arc 中的闭包>?

问题描述

我正在尝试将动态语言转换为 Rust,而闭包是最难实现的部分。

我试过使用 a Arc<Mutex<dyn FnMut>>,但它不支持递归。

use std::sync::{Arc, Mutex};

type Data = Arc<DataUnpack>;
enum DataUnpack {
    Number(f64),
    Function(Box<Mutex<FnMut(Vec<Data>) -> Data>>),
}

fn call(f: Data, args: Vec<Data>) -> Data {
    if let DataUnpack::Function(v) = &*f {
        let f = &mut *v.lock().unwrap();
        f(args)
    } else {
        panic!("TYPE ERR")
    }
}

fn lambda(f: Box<FnMut(Vec<Data>) -> Data>) -> Data {
    Arc::new(DataUnpack::Function(Box::new(Mutex::new(Box::leak(f)))))
}

fn main() {
    let f: Arc<Mutex<Data>> = Arc::new(Mutex::new(Arc::new(DataUnpack::Number(0.0))));
    *f.lock().unwrap() = {
        let f = f.clone();
        lambda(Box::new(move |xs| {
            println!("Ha");
            call(f.lock().unwrap().clone(), xs.clone())
        }))
    };
    call(f.lock().unwrap().clone(), vec![]);
}

操场

它显示一个Ha然后停止。我哪里错了?

标签: recursionrustreference-counting

解决方案


推荐阅读