rust - 如何解释 read_until 的签名以及 Tokio 中的 AsyncRead + BufRead 是什么?

标签 rust rust-tokio

我正在尝试理解 Rust 中的异步 I/O。以下代码基于 Katharina Fey 的片段 Jan 2019 talk这对我有用:

use futures::future::Future;
use std::io::BufReader;
use tokio::io::*;

fn main() {
    let reader = BufReader::new(tokio::io::stdin());
    let buffer = Vec::new();

    println!("Type something:");
    let fut = tokio::io::read_until(reader, b'\n', buffer)
        .and_then(move |(stdin, buffer)| {
            tokio::io::stdout()
                .write_all(&buffer)
                .map_err(|e| panic!(e))
        })
        .map_err(|e| panic!(e));

    tokio::run(fut);
}

在找到该代码之前,我尝试从read_until中找出它。文档。

如何解释 read_until 的签名以在上面的代码示例中使用它?

pub fn read_until<A>(a: A, byte: u8, buf: Vec<u8>) -> ReadUntil<A> 
where
    A: AsyncRead + BufRead, 

具体来说,我如何通过阅读文档知道传递给 and_then 闭包的参数是什么以及预期的结果?

最佳答案

参数and_then

不幸的是,Rust 文档的标准布局使得 futures 很难理解。

read_until 开始您链接的文档,我可以看到它返回 ReadUntil<A> 。我将点击它转到 ReadUntil documentation .

该返回值描述为:

A future which can be used to easily read the contents of a stream into a vector until the delimiter is reached.

我希望它能够实现 Future特质——我可以看到确实如此。我还假设 Item future 解析为某种向量,但我不知道到底是什么,所以我继续挖掘:

  1. 首先,我查看“Trait Implements”并找到 impl<A> Future for ReadUntil<A>
  2. 我点击[+]扩展器

最后我看到了关联的type Item = (A, Vec<u8>) 。这意味着它是 Future这将返回一对值: A ,所以它大概给了我原来的 reader我传入的,加上字节向量。

当 future 解析到这个元组时,我想用and_then附加一些额外的处理。 。这是 Future 的一部分特征,这样我就可以进一步向下滚动找到该函数。

fn and_then<F, B>(self, f: F) -> AndThen<Self, B, F>
where
    F: FnOnce(Self::Item) -> B,
    B: IntoFuture<Error = Self::Error>,
    Self: Sized,

函数and_then被记录为采用两个参数,但是 self当使用点语法到函数时,由编译器隐式传递,这告诉我们可以编写 read_until(A, '\n', buffer).and_then(...) 。文档中的第二个参数f: F ,成为传递给 and_then 的第一个参数在我们的代码中。

我可以看到f是一个闭包,因为类型 F显示为FnOnce(Self::Item) -> B (如果我点击 Rust book closure chapter 的链接。

关闭f传入的内容为Self::Item作为参数。我刚刚发现Item(A, Vec<u8>) ,所以我希望写类似 .and_then(|(reader, buffer)| { /* ... /* }) 的内容

AsyncRead + BufRead

这对可以阅读的阅读器类型施加了限制。创建的 BufReader 实现 BufRead .

Tokio 提供了有用的 an implementation of AsyncRead for BufReader 所以我们不必担心,我们可以继续使用 BufReader .

关于rust - 如何解释 read_until 的签名以及 Tokio 中的 AsyncRead + BufRead 是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56402818/

相关文章:

rust - tokio::net::TcpStream是如何实现tokio::prelude::Stream的?

rust - 不能借用为不可变的,因为它在函数参数中也被借用为可变的

返回通用特征的 Rust 函数

rust - 使用 Tokio 0.2 生成非静态 future

rust - 如何在 tokio_core::io::Codec::decode(...) 中实现零拷贝?

asynchronous - 如果某些情况发生,则完成 future

rust - 更新非常旧的代码时出现问题

rust - 特质 `std::convert::From<cli::Opts>`未实现

rust - 如何在自定义序列化和反序列化中使用 "flatten"之类的东西