Rust 在线程内使用闭包

Rust 在线程内使用闭包,rust,Rust,我试图在一个线程中使用闭包,但经过2个小时的尝试后,我似乎找不到如何使用。这是文件discord\u async.rs: use discord::*; use discord::model::Event; use std::sync::Arc; use shared_mutex::SharedMutex; use std::thread; pub struct DiscordAsync { client: Arc<SharedMutex<Discord>> }

我试图在一个线程中使用闭包,但经过2个小时的尝试后,我似乎找不到如何使用。这是文件
discord\u async.rs

use discord::*;
use discord::model::Event;
use std::sync::Arc;
use shared_mutex::SharedMutex;
use std::thread;

pub struct DiscordAsync {
    client: Arc<SharedMutex<Discord>>
}

impl DiscordAsync {
    pub fn new(bot_token: &str) -> DiscordAsync {
        let client = Arc::new(SharedMutex::new(Discord::from_bot_token(bot_token).unwrap()));
        DiscordAsync {
            client: client
        }
    }

    pub fn start<F>(&self, mut event_handle: F) -> () where F: FnMut(Arc<Event>, Arc<SharedMutex<Discord>>) + Send + 'static {
        let (mut connection, _) = self.client.read().unwrap().connect().unwrap();
        let event_handle = Arc::new(SharedMutex::new(event_handle));

        loop {
            let event = Arc::new(connection.recv_event().unwrap());
            let event_handle = event_handle.read().unwrap();

            // Start a thread so we don't block shit
            thread::spawn(move || {

                // Match event to actions we want to handle
                event_handle(event.clone(), self.client);
            });
        }
    }
}
extern crate colored;
extern crate discord;
extern crate shared_mutex;

mod discord_async;

use std::thread;
use colored::*;
use discord::*;
use discord::model::{Event, Channel, ServerId};
use discord_async::DiscordAsync;

fn main() {
    // Server info
    let bot_token = "...";
    let server_id = ServerId(12345);

    let dis_async = DiscordAsync::new(bot_token);
    dis_async.start(|event, _| {
        println!("{:?}", event);
    });
}
编译器消息:

编译bottest1 v0.1.0(file:///home/kindlyfire/Documents/dev/rust/bottest1)

错误[E0477]:类型为`[closure@src/discord_async.rs:29:18:33:5事件处理:共享互斥体::SharedMutexReadGuard您锁定互斥体,然后尝试将锁定的对象移动到线程中。这是错误的方法。您需要克隆
Arc
并将其移动到线程中

编辑:我还没有测试过,但类似的方法应该可以:

pub fn start<F>(&self, mut event_handle: F) -> ()
    where F: FnMut(Arc<Event>, Arc<SharedMutex<Discord>>) + Send + 'static
{
    let (mut connection, _) = self.client.read().unwrap().connect().unwrap();
    let event_handle = Arc::new(SharedMutex::new(event_handle));

    loop {
        let event = Arc::new(connection.recv_event().unwrap());
        let event_handle = event_handle.clone();
        let client = self.client.clone();

        // Start a thread so we don't block shit
        thread::spawn(move || {

            // Match event to actions we want to handle
            event_handle.read().unwrap()(event, client);
        });
    }
}
pub fn start(&self,mut event_handle:F)->()
式中F:FnMut(弧、弧)+发送+静态
{
let(mut connection,u)=self.client.read().unwrap().connect().unwrap();
让event_handle=Arc::new(SharedMutex::new(event_handle));
环路{
let event=Arc::new(connection.recv_event().unwrap());
让event_handle=event_handle.clone();
让client=self.client.clone();
//开始一个线程,这样我们就不会阻塞狗屎
线程::生成(移动| |{
//将事件与我们要处理的操作匹配
事件句柄.read().unwrap()(事件,客户端);
});
}
}
请注意,我们在lambda外部创建
的克隆,然后在内部使用它们。除了
事件
,我们不克隆它,因为我们可以移动现有的一个指针。这会将克隆移动到lambda中。不过,您可能会在
事件
周围删除
。您没有任何其他指向它的指针都不需要让它保持活动状态,而且它必须是
Send
(我认为
&t
只是
Sync
如果
t
Send

如果这不起作用,请使用新的编译器错误进行更新


作为术语的旁注,“句柄”是指某些资源的对象。处理事件的函数是“句柄r”.

它不起作用=>我只是把读心水晶球放错地方了,你能说得更清楚一点吗…比如包括任何编译器错误吗?请生成一个。我添加了编译器错误消息和我的
Cargo.toml
。你能给我提供实际的固定代码吗?在做了多次编辑之后,我认为应该按照你说的做d我无法让它工作。我也在两天前开始使用Rust,所以它是相当新的。它现在导致
无法在
事件句柄上以可变的形式借用不可变的借用内容。read().unwrap()
,即使我在函数中每次
let
之后添加
mut
pub fn start<F>(&self, mut event_handle: F) -> ()
    where F: FnMut(Arc<Event>, Arc<SharedMutex<Discord>>) + Send + 'static
{
    let (mut connection, _) = self.client.read().unwrap().connect().unwrap();
    let event_handle = Arc::new(SharedMutex::new(event_handle));

    loop {
        let event = Arc::new(connection.recv_event().unwrap());
        let event_handle = event_handle.clone();
        let client = self.client.clone();

        // Start a thread so we don't block shit
        thread::spawn(move || {

            // Match event to actions we want to handle
            event_handle.read().unwrap()(event, client);
        });
    }
}