如何在期货链中使用Result类型中包含的套接字?

时间:2018-08-24 17:21:42

标签: 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

  

请注意,res是包含原始套接字的Result。这样,我们就可以在同一套接字上对其他读取或写入进行排序。

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

1 个答案:

答案 0 :(得分:5)

请先重新阅读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,
     

对未来何时完成并传递结果进行计算   到提供的闭包f的将来。

     

此功能可用于确保计算运行   未来的结论。提供的封包将产生   Result (将来一旦完成)。

将此与您正在使用的 other 函数进行对比,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, 
     

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

     

此功能可用于将两个期货链接在一起并确保   最终的未来直到双方都完成后才能解决。的   所提供的关闭是这个未来的成功结果,并且   返回另一个可以转换为未来的值。


一种解决方案是仅在通过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
}

另请参阅: