Rust Future 小结:几种 Future 的写法,本质是一样的。

原创
2020/05/27 14:40
阅读数 706

Future 牵扯的概念比较多,Future 可以多个串起来当作一个 task,然后众多 task 再送入线程池,线程在执行的时候会阻塞在 block_on() 调用等待事件。 比如 epoll 事件,它会驱动最靠近的 Future::poll(),然后再一层一层的 Future::poll() 执行,最后返回值。

Rust Future 坑很多,早期版本和 nightly 版本有差异。比如早期版本
Future<Item=i32, Error=Error>
后来改为了写法:
Future<Output=Result<i32,Error>>

以下为三种写法,其实都是语法糖,最后都会转为最后最麻烦那种!

use futures::future::Future;
use futures::task::{Poll, Context};
use futures::future::{ok, err, join};
use std::error::Error;
use std::result::Result;
use std::pin::Pin;

// 最方便的写法
async fn fn1() -> i32 {
    111
}

fn fn2() -> impl Future<Output = u32> {
    async {
        222
    }
}

struct Foo {
    name: &'static str,
    age:i32,
}

impl Future for Foo {
    type Output = i32;
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        println!("peding..., self.age: {}", self.age);
        Poll::Ready(self.age)

        // 如果一直返回 Pending, 会一直卡死在这里
        //Poll::Pending
    }
}

fn fn3() -> Foo {
    Foo{name:"aaa", age:333}
}

fn main() {
    let f1 = futures::executor::block_on(fn1());
    println!("f1: {}", f1);

    let f2 = futures::executor::block_on(fn2());
    println!("f2: {}", f2);

    let foo = Foo{name:"abc", age:2222};
    let f3 = futures::executor::block_on(foo);
    println!("f3: {}", f3);
}

main() 函数如果要使用 .await,则本身会被改为 Future,需要使用宏转换一下写法:

#[tokio::main]
async main() {
      let f1 = fn1().await;
	  let f2 = fn2().await;
}

会被转化为:

futures::executor::block_on(async {
    main() {
      let f1 = fn1().await;
	  let f2 = fn2().await;
	}
})
展开阅读全文
打赏
0
1 收藏
分享
加载中
更多评论
打赏
0 评论
1 收藏
0
分享
返回顶部
顶部