我正在尝试在线程中使用闭包,但经过2个小时的尝试后,我似乎无法找到。这是文件discord_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);
});
}
}
}
我在main.rs
:
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);
});
}
编译器消息:
Compiling bottest1 v0.1.0 (file:///home/kindlyfire/Documents/dev/rust/bottest1)
error[E0477]: the type `[closure@src/discord_async.rs:29:18: 33:5 event_handle:shared_mutex::SharedMutexReadGuard<'_, F>, event:std::sync::Arc<discord::model::Event>, self:&discord_async::DiscordAsync]` does not fulfill the required lifetime
--> src/discord_async.rs:29:4
|
29 | thread::spawn(move || {
| ^^^^^^^^^^^^^
|
= note: type must outlive the static lifetime
我的Cargo.toml
:
[package]
name = "bottest1"
version = "0.1.0"
authors = ["kindlyfire"]
[dependencies]
discord = "0.7.0"
colored = "1.4"
shared-mutex = "0.2"
我已经看了很多不同的方法,包括在SO上,但是找不到任何有用的方法。
答案 0 :(得分:1)
锁定互斥锁,然后尝试将锁定的对象移动到线程中。这是错误的方式。您需要克隆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);
});
}
}
请注意,我们在lambda外部创建Arc
的克隆,然后在里面使用它们。除了我们没有克隆的event
,因为我们移动我们拥有的一个指针就可以了。这将克隆移动到lambda中。不过,你可能可以摆脱Arc
周围的Event
。你没有任何其他指示,不需要保持它活着,无论如何它必须是Send
(我认为&T
只是Sync
如果T
是Send
)。
如果这不起作用,请使用新的编译器错误进行更新。
作为术语的旁注,&#34;句柄&#34;是一个引用某些资源的对象。处理事件的函数是&#34;句柄 r &#34;。