【译】Rust 中的流式接口指南

一旦你更喜欢或关注我们钟爱的 REST api 的简单请求/响应协议,而不太了解流、异步生成器等概念,就容易出现一些问题。对于 Rust 来说尤其如此。当你决定在 GRPC 中使用 tonic 或在 Websocket 中使用 tokio tungstenite 时,这些库中唯一可用的接口都是基于流的。这就是为什么本文关注于在 Rust 的上下文中引入流。.........
摘要由CSDN通过智能技术生成
  • A Guided Tour of Streams in Rust(【译】Rust 中的流式接口指南)
  • 原文链接:https://www.qovery.com/blog/a-guided-tour-of-streams-in-rust
  • reddit 链接:https://www.reddit.com/r/rust/comments/uotnwc/a_guided_tour_of_streams_in_rust/
  • 原文作者:Romain Gérard
  • 译文来自:https://github.com/suhanyujie/article-transfer-rs/
  • ps:水平有限,如有不当之处,欢迎指正。
  • 标签:Rust,stream

导读

我们在调研如何给 Qovery 基础架构编写 GRPC 或 Websocket 服务器时,我了解到了很多资源。但是,尽管许多指南提供了对 future 的深入见解,但它们严重缺乏关于 Stream API 在 Rust 中如何工作的文档。更重要的是,如何正确使用它。遗憾的是,我们不能对视而不见。一旦你更喜欢或关注我们钟爱的 REST api 的简单请求/响应协议,而不太了解流、异步生成器等概念,就容易出现一些问题。对于 Rust 来说尤其如此。当你决定在 GRPC 中使用 tonic 或在 Websocket 中使用 tokio tungstenite 时,这些库中唯一可用的接口都是基于流的。这就是为什么本文关注于在 Rust 的上下文中引入流。

正文

流(stream)是什么?

异步世界来看,流是一个迭代器。如果习惯于同步世界,你观察一个迭代器,它看起来就像这样:

Iterator<MyItem>

它表示可以检索的 0…N 的 MyItem 序列,那迭代器呢。很有可能,你已经亲眼见过了。它们早就出现在 Java 1.2 版中,你也可以在 C++ 标准库中找到它们,以及在 [Python] 中(https://wiki.python.org/moin/Iterator) 也能看到。迭代器通常在你想要迭代一个集合(比如一个列表,一个向量,一个树等等)时用到。它是一种常见的抽象,可以与集合实现解耦,并表示可以以线性方式检索的一系列项。在 Rust 中,迭代器只有 2 个特殊项:

pub trait Iterator {
   
    type Item;
    fn next(&mut self) -> Option<Self::Item>;
}
  • 一个关联类型 Item,表示迭代器将返回的对象类型
  • 一个 next() 方法,用于返回 Option 包裹的 Item 类型对象

**为什么是 Option?**当返回类型有可能是 None 时,使用 Option 是有用的,因为它可以告诉你迭代器没有任何元素剩余,现在耗尽了。如果你以 Java API 为例,它有两个方法 — 一个叫做 next(),这和 Rust 中一样,不过 Rust 直接返回一个 Item;另一个方法叫做 hasNext()。作为开发人员,在调用 next() 之前调用 hasNext() 取决于你。但如果是忘记这样做,就构成了一个逻辑错误,可能导致程序崩溃。通过合并 hasNext()next(),并返回一个 Option, Rust 防止了这种错误的产生,并为开发人员提供了一个更安全的 API 接口。

流:异步迭代器

现在我们已经讨论了迭代器是什么,让我们回到流(streams)。正如我们所看到的,流是迭代器的异步版本。我们看看它的定义:

pub trait Stream {
   
    type Item;
    fn poll_next(
        self: Pin<&mut Self>,
        cx: &mut Context
    ) -> Poll<Option<Self::Item>>;
}

等等, poll/pin 是什么?让我们先把它们放在一边,然后修改定义以更好地理解:

pub trait Stream {
   
    type Item;
    fn next(self: &mut Self ) -> impl Future<Output = Option<Self::Item>>;
    // Warning, the trait does not really return a Future, it is more correct to say that Stream trait is also a Future
    // but for the sake of the explanation, we are going to say that next returns a future
}

由于特殊的 async 关键字,在 Rust 中返回 Future 的方式可以不用。所以,如果我们再次改变定义,流的定义就相当于:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值