rust中的Stream和Future

在 Rust 中,StreamFuture 是异步编程的重要概念,它们用于处理异步操作和数据流。

Future

Future 表示一个可能在将来完成的异步计算。它类似于其他编程语言中的 PromiseTask

定义

Future 是一个包含一个 poll 方法的 trait:

use std::task::{Context, Poll};

pub trait Future {
    type Output;

    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
}
  • poll 方法:检查 Future 是否已经完成。如果完成,返回 Poll::Ready(T),否则返回 Poll::Pending
  • Output 类型:表示 Future 完成时的返回值类型。
示例

下面是一个简单的 Future 示例:

use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
use std::time::{Duration, Instant};
use tokio::time::sleep;

struct MyFuture {
    when: Instant,
}

impl Future for MyFuture {
    type Output = &'static str;

    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        if Instant::now() >= self.when {
            Poll::Ready("Hello, world!")
        } else {
            // 重新注册 waker,当时间到达时唤醒任务
            cx.waker().wake_by_ref();
            Poll::Pending
        }
    }
}

#[tokio::main]
async fn main() {
    let future = MyFuture {
        when: Instant::now() + Duration::from_secs(2),
    };
    let result = future.await;
    println!("{}", result);
}

在这个例子中,MyFuture 表示一个异步操作,它将在指定时间后完成并返回一个字符串。
wake_by_ref:通过引用唤醒任务,而不消耗 Waker,用于在条件不满足时重新注册任务,以便在未来某个时间点再次尝试。

Stream

Stream 表示一个异步的数据流,它可以产生一系列值。在某种程度上,它类似于 Iterator,但用于异步上下文中。

定义

Stream 是一个包含一个 poll_next 方法的 trait:

use std::task::{Context, Poll};

pub trait Stream {
    type Item;

    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>;
}
  • poll_next 方法:检查 Stream 是否有新的数据。如果有,返回 Poll::Ready(Some(T)),如果流结束,返回 Poll::Ready(None),否则返回 Poll::Pending
  • Item 类型:表示 Stream 中产生的值的类型。
示例

下面是一个简单的 Stream 示例:

use std::pin::Pin;
use std::task::{Context, Poll};
use std::time::{Duration, Instant};
use tokio::time::sleep;
use futures::stream::Stream;

struct MyStream {
    count: usize,
    when: Instant,
}

impl Stream for MyStream {
    type Item = usize;

    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
        if self.count >= 5 {
            Poll::Ready(None)
        } else if Instant::now() >= self.when {
            let count = self.count;
            self.get_mut().count += 1;
            self.get_mut().when = Instant::now() + Duration::from_secs(1);
            Poll::Ready(Some(count))
        } else {
            cx.waker().wake_by_ref();
            Poll::Pending
        }
    }
}

#[tokio::main]
async fn main() {
    let stream = MyStream {
        count: 0,
        when: Instant::now(),
    };

    futures::pin_mut!(stream);

    while let Some(item) = stream.next().await {
        println!("Got: {}", item);
    }
}

在这个例子中,MyStream 表示一个异步的数据流,它每秒钟产生一个值,最多产生五个值。

async/await

Rust 提供了 async/await 语法来简化 FutureStream 的使用。async 函数返回一个实现了 Future 的对象,而 await 表达式则阻塞当前任务,直到 Future 完成。

示例
#[tokio::main]
async fn main() {
    async fn say_hello() -> &'static str {
        "Hello, world!"
    }

    let result = say_hello().await;
    println!("{}", result);
}

这个例子展示了如何使用 async 函数和 await 表达式来处理异步操作。

总结

  • Future:表示将来可能完成的异步计算,通过 poll 方法检查是否完成。
  • Stream:表示异步的数据流,通过 poll_next 方法生成一系列值。
  • async/await:简化了 FutureStream 的使用,使异步编程更加直观和易读。

Rust 的异步编程模型强大且灵活,适用于各种高性能和并发场景。通过理解 FutureStream 以及 async/await 语法,你可以编写高效的异步代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值