我有一个结构体RabbitMQBackend
,它实现了Backend
特质,如下所示:
pub trait Backend {
// Start consuming message from the queue.
fn pull(&self, sender: &Sender<String>);
}
pub struct RabbitMQBackend {
// Some fields ...
}
impl Backend for RabbitMQBackend {
fn pull(&self, sender: &Sender<String>) {do something...}
}
我正在创建一个这个结构体的实例,如下所示:
let rmq_backend = RabbitMQBackend::new("amqp://user:password@localhost:5672/", "testqueue2");
let mut consumer = ThreadConsumer::new();
consumer.consume(&rmq_backend);
其中ThreadConsumer
是:
pub struct ThreadConsumer {
pub sender: Sender<String>,
pub receiver: Receiver<String>,
}
impl Consumer for ThreadConsumer {
fn new() -> Self {
let (sender, receiver) = bounded(3);
ThreadConsumer {
sender: sender,
receiver: receiver,
}
}
fn consume(&mut self, backend: &impl Backend) {
let consumer = thread::spawn(move || {
backend.pull(&self.sender);
});
}
}
问题是我正试图在一个独立的线程中调用
backend.pull
函数,但我收到了这个错误:error[E0277]: `impl Backend` cannot be shared between threads safely
--> src/consumer/thread_consumer/thread_consumer.rs:23:24
|
23 | let consumer = thread::spawn(move || {
| ^^^^^^^^^^^^^ `impl Backend` cannot be shared between threads safely
|
= help: the trait `std::marker::Sync` is not implemented for `impl Backend`
help: consider further restricting this bound with `+ std::marker::Sync`
--> src/consumer/thread_consumer/thread_consumer.rs:20:37
|
20 | fn consume(&mut self, backend: &impl Backend) {
| ^^^^^^^^^^^^
= note: required because of the requirements on the impl of `std::marker::Send` for `&impl Backend`
= note: required because it appears within the type `[closure@src/consumer/thread_consumer/thread_consumer.rs:23:38: 25:10 backend:&impl Backend, self:&mut consumer::thread_consumer::thread_consumer::ThreadConsumer]
注1:我尝试为Backend trait 和 RabbitMQBackend 结构体实现Send和Sync trait,如下所示:
pub trait Backend: Send + Sync {
// Start consuming message from the queue.
fn pull(&self, sender: &Sender<String>);
}
pub struct RabbitMQBackend {
// Some fields ...
}
unsafe impl Send for RabbitMQBackend {}
unsafe impl Sync for RabbitMQBackend {}
然后像这样传递了后端函数参数:
fn consume(&mut self, backend: &impl Backend + Send + Sync) {...}
但是出现了以下错误:
= note: but, the lifetime must be valid for the static lifetime...
= note: ...so that the types are compatible:
我该如何解决这个问题?
backend: &(impl Backend + Sync)
)?通常情况下,Send
和Sync
标记特质不应该手动实现。 - Aloso