在Rust中的线程之间发送特征对象 [英] Sending trait objects between threads in Rust

查看:101
本文介绍了在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆