task - 将 Vec<Struct> 传递到新任务中

标签 task rust lifetime

我正试图通过 Vector将自定义结构转换为在新任务中执行的函数。我已经实现了 Clone特征,我认为这是需要的,但显然我想传递的向量需要实现 'static+Send为了在闭包的环境中被捕获。我不确定如何才能满足这些生命周期规范?

我正在尝试从这个函数开始这个过程

pub fn start(server: Server, ip: &str, port: u16) {

    // Other things happening

    spawn(proc() {
        event_loop(server.events.clone(), from_conn_pool)
    });
}

fn event_loop(events: Vec<Event>, from_conn_pool: Receiver<Vec<Socket>>) {
    // Wizard magic
}

我收到的错误是:error: cannot capture variable of type <code>rustic_io::server::Server<'_></code>, which does not fulfill <code>'static+Send</code>, in a bounded closure

server.rs

pub struct Server<'a> {
    pub sockets: Vec<Socket<'a>>,
    pub events: Vec<Event<'a>>
}

事件.rs

pub struct Event<'a> {
    pub name: String,
    pub execute: &'a fn(data: &str, server: super::Server)
}

impl<'a> Event<'a> {
    pub fn new(event: &str, execute: &'a fn(data: &str, server: super::Server)) -> Event<'a> {
        Event {
            name: String::from_str(event),
            execute: execute
        }
    }
}

impl<'a> Clone for Event<'a> {
    fn clone(&self) -> Event<'a> {
        Event {
            name: self.name.clone(),
            execute: self.execute
        }
    }
}

事件循环任务将循环遍历各种流,如果读取的数据与特定事件名称匹配,它会触发与其关联的函数。从 Rust 文档中,我可以看到您可以像这样调用 spawn 来启动命名函数:

// Print something profound in a different task using a named function
fn print_message() { println!("I am running in a different task!"); }
spawn(print_message);

我认为这是我应该生成任务的方式,因为它是一个正在执行的命名函数。我假设是因为我称它为 spawn(proc(){ ... }) ,它期望所有进入的东西都是闭包拥有的吗?我试过将任务生成为 spawn(event_loop(arg, arg2)) ,但编译器给我:error: mismatched types: expected <code>proc():Send</code> but found <code>()</code> (expected fn but found ())

在这一点上,我不知道如何获得 Vec<Event>进入新任务?

最佳答案

A proc()拥有它的环境。任何进入其中的东西都必须能够移入其中,因此必须是 'staticSend .

这意味着当你写

spawn(proc() {
    event_loop(server.events.clone(), from_conn_pool)
});

它正在 try catch server (因为 server.events.clone() ——请注意它是如何捕获整个 Server 的;它不太可能是你想要的(你可以在 proc 之前做类似 let events = server.events.clone(); 的事情,然后使用 events ,或者你可以只是承认 clone() 调用是多余的)和 from_conn_pool 。你的问题是 server :它不一定是 'static ,因为你没有为类型指定任何生命周期,所以它被推断为任意生命周期;也就是说,它可能包含一个非静态生命周期的事件,显然不能将其移动到新任务。对于初学者来说,您需要 Server<'static>

但问题随之而来:你为什么要使用 &'a fn(…)而不仅仅是 fn(…)作为你的类型?如果你把整个引用的东西放在那里,你的问题就会消失。

关于task - 将 Vec<Struct> 传递到新任务中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25286096/

相关文章:

c# - 如何重载函数以接受异步和同步版本的回调参数

c# - 返回 Task<string> 的方法

error-handling - 如何使用自定义结构实现错误

rust - 返回对链表元素的引用

Windows 8 NetScheduleJobAdd 不支持请求

rust - 如何在 WebAssembly 中从 Rust 返回一个字符串(或类似字符串)?

rust - 如何防止 `rust doc` 向文档添加依赖项?

rust - 如何运行特定模块下的所有测试功能?

rust - 在 Rust 中,如何将具有生命周期的对象推送到向量中?

C#。取消任务时 SemaphoreSlim.WaitAsync 不会抛出 OperationCanceledException