Rust : async、await 初探

释放双眼,带上耳机,听听看~!

rust 中的语法await!正式改成.await, 关于Future这套东东,很有必要了解。象actix-web也已经1.0了,里面其实也是到处Future这套。async、await这套东东,是rust的硬知识。

一、async和await的几种形式

“async和其他Future是懒惰的:它们在运行之前什么都不做。运行Future的最常见方式是.await它。当在Future上调用.await时,它将尝试运行以完成它。如果Future被阻止,它将让出当前线程。当可以取得更多进展时,执行者将获取 Future并将继续运行,以便.await解决。”

1、async
(1)async fn

当然,也有很多情况,比如函数中有.await; 也可能没有.await的不同情况。这种也会导致,返回值也完全不一样。
比如,


1
2
3
4
5
1      async fn compute(){
2          println!("async->");
3      }
4
5

这个相当于:[只是相当于]


1
2
3
4
5
1       fn compute()->impl Future<Output = ()>{
2          println!("async->");
3      }
4
5

(2)async move

这种情况是,函数外面没有async 标识,此时,async move{}为返回值,放在函数里面,返回值是Future这套trait 的静态分发方式。
“async move块将获取它引用变量的所有权,允许它活得比目前的范围长,但放弃了与其他代码分享那些变量的能力”。

比如:


1
2
3
4
5
6
7
8
9
10
11
1  fn compute_01() -> impl Future<Output =Result<(),String>>{
2    async move{
3       for i in 1..10000{
4          let _ = i*2;
5       }
6       println!("=>01 it is over!");
7       Ok(())
8    }
9  }
10
11

(3)async闭包


1
2
3
4
5
6
7
8
9
1  fn compute_05(value:i32)->impl Future<Output=i32>{
2     let closure = async move |v:i32|{
3        compute_03().await;
4        v+1
5     };
6     closure(value)
7  }
8
9

2 、await
async并不必然就需要用await,但设计的初衷是想等.await调用。

在.await的调用上,需要注意两个方面,一方面是,什么情况下能用上.await;另一方面是, 用上.await函数本身有什么要求?
相当于,一个是从逻辑实质上的要求;另一个是外在形式上的要求;

(1)能用await的情况

await的用法很简单,一般主要有以下两个这中的一个条件,一种是显示的;一种是隐式的;

A、显示方式:调用的函数中与async相对应的安排的;比如,async; async move;

这种情况好理解,不详述。

B、隐式方式:没有明显的async相对应的安排,但函数的返回值实现了Future trait.

这种情况,是一种隐式的情况。比如,


1
2
3
4
5
6
7
8
9
10
11
12
1  struct data{
2       price :Vec<f64>
3  }
4  fn  get_data(length: i64) ->data{
5  }
6  //但data 实现了Future trait, 即
7  impl Future for data{
8     // 省略......
9  }
10//即实现的函数,有Poll<Self::Output>
11
12

(2)await有用时,函数体外面是一定有async这个壳套着的;

也就是说,只有函数的签名中有async,才允许用.await的;


1
2
3
4
5
1async fn v(){
2     m().await // .await 是因为v()外面的签名,一定有一个async.
3}
4
5

另外,说明一下,当函数的返回值形式实现了impl Future<Output =Result<>>类型时,可以用.await?的形式。

3、block_on()

另外,提一下block_on(). 如果没有这个函数,所有的异步相当于“箭射出后,但收不回来”。
block_on() 相当于让这个异步安排强制完成。

二、实例

1、相关说明
(1)#![feature(async_await)]
有时,会更长一些,比如
#![feature(async_await, await_macro, futures_api)],具体来说,
async_await 增加了对 async fn 语法的支持。
await_macro 增加了对 await! 宏的支持。
futures_api 增加了对 nightly std::future 和 std::task 模块的支持,这些模块定义了核心Future特征和依赖类型。

(2)并在nightly的环境中

2、代码


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
1  #![feature(async_await)]
2  use std::thread;
3  use std::time::Duration;
4  use futures::{Future};
5  use futures::executor::block_on;
6
7  fn compute_01() -&gt; impl Future&lt;Output =Result&lt;(),String&gt;&gt;{
8    async move{
9       for i in 1..10000{
10          let _ = i*2;
11       }
12       println!(&quot;=&gt;01 it is over!&quot;);
13       Ok(())
14    }
15  }
16  async fn compute_02(){
17      println!(&quot;=&gt;02 is entering....&quot;);
18      compute_01().await;
19      //compute_04().await;
20      println!(&quot;=&gt;02 is over!&quot;);
21  }
22  async fn compute_03(){
23    println!(&quot;=&gt;03 is entering....&quot;);
24    for i in 1..10000{
25       let _ = i*2;
26    }
27    println!(&quot;=&gt;03 it is over!&quot;);
28  }
29  fn compute_04(){
30     println!(&quot;=&gt; 04 is entering....&quot;)
31  }
32
33  fn compute_05(value:i32)-&gt;impl Future&lt;Output=i32&gt;{
34     let closure = async move |v:i32|{
35        compute_03().await;
36        v+1
37     };
38     closure(value)
39  }
40  fn main() {
41    block_on(compute_02());
42    //compute_03();
43    block_on(compute_03());//必须把这些异步跑完
44
45    let val = block_on(compute_05(6));
46    println!(&quot;val :{:?}&quot;,val);
47    println!(&quot;hello world!&quot;);
48    thread::sleep(Duration::from_millis(500000));
49  }
50
51

三、输出结果


1
2
3
4
5
6
7
8
9
10
11
1=&gt;02 is entering....
2=&gt;01 it is over!
3=&gt;02 is over!
4=&gt;03 is entering....
5=&gt;03 it is over!
6=&gt;03 is entering....
7=&gt;03 it is over!
8val :7
9hello world!
10
11

给TA打赏
共{{data.count}}人
人已打赏
安全技术

C++设计模式

2022-1-11 12:36:11

气候事件

中央气象台7月8日18时继续发布台风蓝色预警

2014-7-9 0:51:33

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索