44

スレッド間で特性オブジェクトを送信したいのですが、それが可能かどうかわかりません。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<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ます。

私はまだRustにかなり慣れていないので、何かが欠けているかどうかはわかりませんが、コンパイラに特性オブジェクトを作成するよう説得する方法がないという印象を受けますSend

現在それが不可能である場合、将来これを可能にする可能性のある作業は現在進行中ですか?

4

1 に答える 1