rust - 如何在 future 链中使用包含在结果类型中的套接字?

标签 rust future rust-tokio

我对 Tokio 文档中的以下工作代码稍作修改:

// Task
let connection = io::read_exact(socket, buf_read)
    .and_then(|(socket, buf_read)| {
        println!("Do something with the received data...");
        for b in &buf_read {
            println!("{}", b);
        }

        // Write to the socket
        let buf_write = vec![19; 30];
        io::write_all(socket, buf_write)
    })
    .then(|res| {
        println!("{:?}", res); // Just for testing
        //Output: Ok((TcpStream, [19, 19, 19, ...]

        println!("Send data...");
        let buf_write = vec![18; 10]; // Fill the buffer with some data
        //
        //How to use the socket contained in res to write the data to the socket
        //    
        Ok(())
    });

the docs it is mentioned

Note that res is a Result that contains the original socket. This allows us to sequence additional reads or writes on the same socket.

如何使用Result中包含的socket向socket写入数据?

最佳答案

请重新阅读The Rust Programming Language ,特别是关于 Recoverable Errors with Result 的章节.然后重新阅读 the library you are using 的文档.

Future::then ,强调我的:

fn then<F, B>(self, f: F) -> Then<Self, B, F>
where
    F: FnOnce(Result<Self::Item, Self::Error>) -> B,
    B: IntoFuture,
    Self: Sized,

Chain on a computation for when a future finished, passing the result of the future to the provided closure f.

This function can be used to ensure a computation runs regardless of the conclusion of the future. The closure provided will be yielded a Result once the future is complete.

将此与您正在使用的其他 函数进行对比,Future::and_then ,强调我的:

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, 

Execute another future after this one has resolved successfully.

This function can be used to chain two futures together and ensure that the final future isn't resolved until both have finished. The closure provided is yielded the successful result of this future and returns another value which can be converted into a future.


一种解决方案是仅通过 and_then 成功处理它:

extern crate tokio; // 0.1.7

use tokio::{io, net::TcpStream, prelude::*};

fn example(socket: TcpStream, buf_read: Vec<u8>) {
    io::read_exact(socket, buf_read)
        .and_then(|(socket, buf_read)| {
            let buf_write = vec![19; 30];
            io::write_all(socket, buf_write)
        }).and_then(|(socket, data)| {
            let buf_write = vec![18; 10];
            io::write_all(socket, buf_write)
        });
    // TODO: use future somehow 
}

如果您想知道失败的原因,那么您可以继续使用then,但您必须以某种方式处理错误:

fn example(socket: TcpStream, buf_read: Vec<u8>) {
    io::read_exact(socket, buf_read)
        .and_then(|(socket, buf_read)| {
            let buf_write = vec![19; 30];
            io::write_all(socket, buf_write)
        }).then(|res| match res {
            Ok((socket, data)) => {
                let buf_write = vec![18; 10];
                io::write_all(socket, buf_write)
            }
            Err(e) => {
                // Do something with the error and return another
                // future that's type-compatible
                unimplemented!()
            },
        });
    // TODO: use future somehow
}

另见:

关于rust - 如何在 future 链中使用包含在结果类型中的套接字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52009155/

相关文章:

reactjs - 如何用 yew 查询和更新 DOM?

scala - 当使用 Futures 执行上下文的其他实现时,程序永远不会结束

rust - 在异步任务中读取 stdin 时为 "blocking annotated I/O must be called from the context of the Tokio runtime"

vector - 如何在不出现错误 "cannot borrow as mutable more than once at a time"的情况下递增向量中的每个数字?

rust - 实现用于复制的项目集合的最佳方法?

java - future 的取消方法文档

sockets - 使用 Tokio futures 的多播 UDP 数据包

rust - 可中止 : Dangling Futures?

rust - 如何调试卡在 `cargo build` 处的 "Updating crates.io index"?

java - 如何等待超时的 ListenableFuture 列表