无法在 fn 项中捕获动态环境 [英] Can't capture dynamic environment in a fn item

查看:51
本文介绍了无法在 fn 项中捕获动态环境的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这段代码中,除了 task_id 之外,一切正常.我希望这个脚本计算 task_id 中的请求数:

In this code everything works except task_id. I want this script to count requests in task_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;

can't capture dynamic environment in a fn item; use the || { ... } closure form instead main.rs:13 task_id += 1;

请帮我解决这个问题 - 如何将 task_id 传递给闭包?

Please help me solve this issue - how can I pass task_id into closure?

推荐答案

为了扩展 Chris Morgan 的回答,这是一个包含相同错误的独立示例:

To expand on Chris Morgan's answer, this is a self-contained example with the same error:

fn main() {
    let mut a = 0;
    fn router() {
        a += 1;
    }
    router();
    println!("{}", a)
}

问题是fn不允许捕获它们的环境,期间.捕获环境并非易事,并且有多种方法可以将变量放入闭包中.闭包实际上是结构,每个捕获的变量都有适当的成员变量.

The problem is that fn items are not allowed to capture their environment, period. Capturing environment is non-trivial, and there are multiple ways to get variables into a closure. Closures are actually structs with the appropriate member variables for each captured variable.

查看克里斯摩根的声明:

Review Chris Morgan's statement:

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

Bear in mind how it may be multi-threaded; at the very least you will need to use some form of mutex to get it to work.

(强调我的).您正在创建一个函数,但您无法控制它的调用方式或时间.众所周知,Nickel 可能会选择从多个线程调用它——这取决于库.事实上,永远不要调用代码task_id += 1

(Emphasis mine). You are creating a function, but you don't get to control how or when it is called. For all you know, Nickel may choose to call it from multiple threads - that's up to the library. As it is, you do not ever call the code task_id += 1!

我不是 Nickel 方面的专家,但您发布的代码似乎无法实现动态路由.但是,您应该可以避免使用宏和 自己构建处理程序,您只需要"实现中间件.该处理程序可能能够包含状态,例如您的 task_id.

I'm no expert on Nickel, but it appears that having dynamic routing is not possible with the code you've posted. However, it should be possible for you to avoid using the macro and construct a handler yourself, you "just" need to implement Middleware. That handler may be able to contain state, like your task_id.

这篇关于无法在 fn 项中捕获动态环境的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆