在Rust中的线程之间发送特征对象 [英] Sending trait objects between threads in Rust
问题描述
我想在线程之间发送一个trait对象,但是不知道是否可能.似乎可能不是,因为它们显然不符合Send
特征.
I'd like to send a trait object between threads, but can't figure out if it's possible. It seems like it might not be, as they apparently do not fulfill the Send
trait.
以下代码演示了我正在尝试做的事情:
The following code demonstrates what I'm trying to do:
use std::{
sync::mpsc::{channel, Receiver, Sender},
thread,
};
trait Bar {
fn bar(&self);
}
struct Foo {
foo: i32,
}
impl Bar for Foo {
fn bar(&self) {
println!("foo: {}", self.foo);
}
}
fn main() {
let foo = Box::new(Foo { foo: 1 }) as Box<dyn Bar>;
let (tx, rx): (Sender<Box<dyn Bar>>, Receiver<Box<dyn Bar>>) = channel();
thread::spawn(move || {
tx.send(foo).unwrap();
});
let sent = rx.recv().unwrap();
sent.bar();
}
此操作失败,并显示以下消息:
This fails with the following message:
error[E0277]: `dyn Bar` cannot be sent between threads safely
--> src/main.rs:25:5
|
25 | thread::spawn(move || {
| ^^^^^^^^^^^^^ `dyn Bar` cannot be sent between threads safely
|
= help: the trait `std::marker::Send` is not implemented for `dyn Bar`
= note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<dyn Bar>`
= note: required because it appears within the type `std::boxed::Box<dyn Bar>`
= note: required because it appears within the type `[closure@src/main.rs:25:19: 27:6 tx:std::sync::mpsc::Sender<std::boxed::Box<dyn Bar>>, foo:std::boxed::Box<dyn Bar>]`
尝试发送一个普通的,未装箱的特征对象会导致很多其他错误,大多数是抱怨未实现Send + Sized
.
Trying to send a plain, unboxed trait object results in a bunch of other errors, mostly complaining about not fulfilling Send + Sized
.
我对Rust还是很陌生,所以我不确定是否缺少某些东西,但是我给人的印象是,没有一种方法可以说服编译器制作特征对象Send
I'm still fairly new to Rust, so I'm not sure if there's something I'm missing, but I get the impression that there isn't a way to convince the compiler to make the trait object Send
.
如果目前无法实现,那么是否正在进行任何工作来在将来允许这样做?
If it isn't currently possible, is there any work currently under way that may allow for this in the future?
推荐答案
有可能.您可以向特征对象添加Send
约束,如下所示:
It's possible. You can add a Send
constraint to a trait object like this:
let foo = Box::new(Foo { foo: 1 }) as Box<dyn Bar + Send>;
let (tx, rx): (Sender<Box<dyn Bar + Send>>, Receiver<Box<dyn Bar + Send>>) = channel();
这篇关于在Rust中的线程之间发送特征对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!