我想在任务之间发送一个特质对象,但无法弄清楚它是否可能。它似乎可能不是,因为它们显然不符合Send
特性。
以下代码演示了我尝试做的事情:
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<Bar>;
let (tx, rx): (Sender<Box<Bar>>, Receiver<Box<Bar>>) = channel();
thread::spawn(move || {
tx.send(foo).unwrap();
});
let sent = rx.recv().unwrap();
sent.bar();
}
此操作失败,并显示以下消息:
error[E0277]: `std::sync::mpsc::Sender<std::boxed::Box<Bar>>` cannot be shared between threads safely
--> src/main.rs:25:5
|
25 | thread::spawn(|| {
| ^^^^^^^^^^^^^ `std::sync::mpsc::Sender<std::boxed::Box<Bar>>` cannot be shared between threads safely
|
= help: the trait `std::marker::Sync` is not implemented for `std::sync::mpsc::Sender<std::boxed::Box<Bar>>`
= note: required because of the requirements on the impl of `std::marker::Send` for `&std::sync::mpsc::Sender<std::boxed::Box<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<Bar>>, foo:std::boxed::Box<Bar>]`
= note: required by `std::thread::spawn`
error[E0277]: the trait bound `Bar: std::marker::Send` is not satisfied
--> src/main.rs:25:5
|
25 | thread::spawn(|| {
| ^^^^^^^^^^^^^ `Bar` cannot be sent between threads safely
|
= help: the trait `std::marker::Send` is not implemented for `Bar`
= note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<Bar>`
= note: required because it appears within the type `std::boxed::Box<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<Bar>>, foo:std::boxed::Box<Bar>]`
= note: required by `std::thread::spawn`
尝试发送一个简单的,未装箱的特征对象会导致一堆其他错误,主要是抱怨没有完成Send + Sized
。
我对Rust还是比较陌生的,所以我不确定是否有我想念的东西,但我得到的印象是没有办法说服编译器制作特征对象Send
。
如果目前无法进行,目前是否有任何可能允许此项工作的工作?
答案 0 :(得分:17)
这是可能的。您可以向特征对象添加Send
约束,如下所示:
let foo = Box::new(Foo { foo: 1 }) as Box<Bar + Send>;
let (tx, rx): (Sender<Box<Bar + Send>>, Receiver<Box<Bar + Send>>) = channel();