echo/echo.rs
1//! Echo Actor 示例
2//!
3//! 该示例展示了如何实现一个最简单的 Actor,并演示以下功能:
4//! - 实现 Actor trait
5//! - 处理 Inbox 消息
6//! - 发送消息到 Actor
7//! - 正确释放 Outbox
8use acty::{Actor, ActorExt, Inbox};
9use futures::StreamExt;
10use std::pin::pin;
11
12/// 一个最简单的 Echo Actor
13///
14/// 该 Actor 处理类型为 `String` 的消息,并将其打印到标准输出。
15/// 注意:该 Actor 没有状态字段,仅展示最基本的用法。
16struct Echo;
17
18/// 实现 `Actor` trait,消息类型为 `String`
19///
20/// 当 Inbox 收到消息时,会逐条打印到标准输出。
21impl Actor for Echo {
22 type Message = String;
23
24 async fn run(self, inbox: impl Inbox<Item = Self::Message>) {
25 // 将 inbox 固定在栈上,以便异步迭代。
26 // 如果需要跨函数传递,可使用 Box::pin 将其固定到堆上(带一点分配开销)。
27 let mut inbox = pin!(inbox);
28
29 // 异步遍历 inbox 中的每条消息
30 while let Some(msg) = inbox.next().await {
31 println!("echo: {}", msg);
32 }
33 }
34}
35
36#[tokio::main]
37async fn main() {
38 // 启动 actor 并获得与之绑定的 outbox
39 let echo = Echo.start();
40
41 // 向 Actor 发送消息
42 // send 返回 Result,当 Actor 已关闭时会返回 Err
43 // 这里使用 unwrap_or(()) 忽略可能的错误
44 echo.send("Hello".to_string()).unwrap_or(());
45 echo.send("World".to_string()).unwrap_or(());
46 echo.send("!".to_string()).unwrap_or(());
47
48 // 解除 outbox 与 actor 的绑定,
49 // 确保 actor 收到所有消息后自然结束
50 echo.detach().await;
51}