Rust Can';t在fn项目中捕获动态环境

Rust Can';t在fn项目中捕获动态环境,rust,Rust,在这段代码中,除了task\u id之外,其他一切都可以工作。我希望此脚本计算任务id中的请求数: use std::thread; use std::thread::sleep_ms; use std::sync::mpsc; #[macro_use] extern crate nickel; use nickel::Nickel; fn main() { let mut server = Nickel::new(); let mut task_id: i64 = 0;

在这段代码中,除了
task\u id
之外,其他一切都可以工作。我希望此脚本计算
任务id
中的请求数:

use std::thread;
use std::thread::sleep_ms;
use std::sync::mpsc;
#[macro_use] extern crate nickel;
use nickel::Nickel;

fn main() {
    let mut server = Nickel::new();
    let mut task_id: i64 = 0;

    server.utilize(router! {
        get "**" => |_req, _res| {
            task_id += 1;
            run_heavy_task(task_id);
            "Yo!"
        }
    });

    server.listen("127.0.0.1:6767");
}

fn run_heavy_task(task_id: i64) {
    let (tx, rx) = mpsc::channel();

    thread::spawn(move || {
        println!("heavy task {} started!", task_id);
        sleep_ms(3000);
        println!("heavy task {} completed", task_id);
        let result = tx.send(());
    });


    //rx.recv();
    //println!("Task {} completed", task_id);
}
错误:

无法捕获fn项目中的动态环境;使用|{…} 以闭包形式代替main.rs:13 task_id+=1


请帮助我解决这个问题-我如何将任务id传递到闭包中?

要详细介绍Chris Morgan的答案,这是一个包含相同错误的独立示例:

fn main() {
    let mut a = 0;
    fn router() {
        a += 1;
    }
    router();
    println!("{}", a)
}
问题是
fn
项目不允许捕获其环境,周期。捕获环境非常重要,有多种方法可以将变量放入闭包中。闭包实际上是结构,每个捕获的变量都有相应的成员变量

回顾Chris Morgan的陈述:

请记住它可能是多线程的;至少你需要使用某种形式的互斥来让它工作

(我的重点)。您正在创建一个函数,但无法控制调用它的方式或时间。据您所知,Nickel可能会选择从多个线程调用它-这取决于库。实际上,从未调用代码
任务\u id+=1


我不是Nickel方面的专家,但是对于您发布的代码来说,动态路由似乎是不可能的。但是,您应该可以避免使用宏,并且“只是”需要实现。该处理程序可能能够包含状态,如您的
任务\u id

路由器
是扩展为函数()的糖。函数不能覆盖变量,这种方法也不起作用。记住它可能是多线程的;至少您需要使用某种形式的互斥来让它工作。@ChrisMorgan正如我所说的,这段代码没有task_id,工作正常:,“这种方法也不会工作”是一个错误的说法。“至少你需要使用某种形式的互斥来让它工作”-我不会在派生函数中更改任务id,所以我不需要互斥。@OZ:我想你误解了,Chris的观点是由
路由器创建的函数更改任务id,并且该函数可能从多个线程调用(据Rust编译器所知),因此即使它可以关闭变量(它不能),您也需要某种形式的同步。