1

我有以下来自 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(())
    });

文档中提到了

请注意,这res是一个Result包含原始套接字的。这允许我们在同一个套接字上对额外的读取或写入进行排序。

如何使用包含在套接字中的套接字Result向套接字写入数据?

4

1 回答 1

5

请从重新阅读Rust 编程语言开始,特别是关于Recoverable Errors with Result的章节。然后重新阅读您正在使用的库的文档。

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,

链上一个未来何时完成的计算,将未来的结果传递给提供的闭包f

此函数可用于确保计算运行,而不管未来的结论如何。一旦未来完成,提供的关闭将被产生 。Result

将此与您正在使用的其他功能进行对比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, 

在这个成功解决后执行另一个未来。

此函数可用于将两个 future 链接在一起,并确保在两者都完成之前不会解析最终的 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
}

也可以看看:

于 2018-08-24T17:52:09.530 回答