1

Actix アクターが 2 人います。MyActor1そのフィールドの 1 つが実装する一般的な特性を定義します。MyActor2定義する必要はなく、どのタイプにマップされるかを知らずにメッセージハンドラーからT呼び出す方法を理解できません。MyActor1::from_registry()MyActor2T

私はこれのバリエーションを試しました:

let addr: Addr<MyActor1<T>> = MyActor1::from_registry();

で定義されてからに追加Tされない限り、どこで/どのように定義するかわからないため、これは機能しません。struct MyActor2<T: Thing>impl<T> Handler<Msg> for MyActor2<T> where T:...

私もこれを試しましたが、Thing実装されていないため機能しませんDefault(それは特性であるため):

let addr: Addr<MyActor1<Thing>> = MyActor1::from_registry();

これが私が使用している例です:

貨物.toml

[package]
name = "actix-example"
version = "0.1.0"
authors = ["me"]
edition = "2018"

[dependencies]
actix = "0.8.1"

main.rs

#![allow(dead_code)]

use actix::prelude::*;

trait Thing {
    fn name(&self) {}
}

#[derive(Default)]
struct One;
impl Thing for One {}

#[derive(Default)]
struct Two;
impl Thing for Two {}

// MyActor1
#[derive(Default)]
struct MyActor1<T: Thing> {
    thing: T,
}

impl<T> Actor for MyActor1<T>
where
    T: Thing + 'static + Default,
{
    type Context = Context<Self>;
}
impl<T> Supervised for MyActor1<T> where T: Thing + 'static + Default {}
impl<T> SystemService for MyActor1<T> where T: Thing + 'static + Default {}
impl<T> Handler<Msg> for MyActor1<T>
where
    T: Thing + 'static + Default,
{
    type Result = ();
    fn handle(&mut self, _msg: Msg, _ctx: &mut Context<Self>) {}
}

// MyActor2
#[derive(Default)]
struct MyActor2;

#[derive(Message)]
struct Msg;
impl Actor for MyActor2 {
    type Context = Context<Self>;
}
impl Supervised for MyActor2 {}
impl SystemService for MyActor2 {}

impl Handler<Msg> for MyActor2 {
    type Result = ();
    fn handle(&mut self, _msg: Msg, _ctx: &mut Context<Self>) {
        let addr = MyActor1::from_registry();
    }
}

fn main() {
    let sys = System::new("test");
    let act1 = MyActor1 {
        thing: One::default(),
    };
    let act2 = MyActor2::default();
    actix::SystemRegistry::set(act1.start());
    actix::SystemRegistry::set(act2.start());
    let _ = sys.run();
}

コードを実行すると、次のエラーが発生します。

error[E0283]: type annotations required: cannot resolve `_: Thing`
  --> src/main.rs:50:20
   |
50 |         let addr = MyActor1::from_registry();
   |                    ^^^^^^^^^^^^^^^^^^^^^^^
   |
note: required by `MyActor1`
  --> src/main.rs:15:1
   |
15 | struct MyActor1<T: Thing> {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^

私はこれがこの例を解決することを知っています:

let addr: Addr<MyActor1<One>> = MyActor1::from_registry();

実行時の状態がわからない場合はどうすればよいMyActor1<T>ですか? たとえば、コマンド ライン引数に基づいて実行時に初期MyActor1化するコードがあったとします。MyActor1<Two>

4

1 に答える 1