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

der*_*cki 1 future rust rust-tokio

我有来自Tokio docs的以下工作代码,我稍微修改了一下:

// 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(())
    });
Run Code Online (Sandbox Code Playgroud)

文档中提到它

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

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

She*_*ter 5

请首先重新阅读Rust编程语言,特别是关于结果可恢复错误的章节.然后重新阅读您正在使用的库的文档.

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,
Run Code Online (Sandbox Code Playgroud)

关于未来结束时的计算链,将未来的结果传递给提供的闭包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, 
Run Code Online (Sandbox Code Playgroud)

在此解决方案成功解决后执行另一个未来.

此功能可用于将两个期货链接在一起,并确保在两个期货完成之前不会解决最终的未来.所提供的关闭产生了这一未来的成功结果,并返回了另一个可以转化为未来的价值.


一种解决方案是仅通过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 
}
Run Code Online (Sandbox Code Playgroud)

如果你想知道失败,那么你可以继续使用,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
}
Run Code Online (Sandbox Code Playgroud)

也可以看看: