【发布时间】:2020-05-11 09:44:48
【问题描述】:
我有一个结构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 特征和 RabbitMQBackend 结构实现 Send 和 Senc 特征,例如:
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 {}
然后通过后端函数arg like
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标记特征应该不手动实现。
标签: rust