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

查看:19
本文介绍了在 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();
}

失败并显示以下消息:

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>]`

尝试发送一个普通的、未装箱的 trait 对象会导致一系列其他错误,主要是抱怨没有实现 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 还是比较陌生,所以我不确定是否有我遗漏的东西,但我的印象是没有办法说服编译器制作 trait 对象 发送.

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天全站免登陆