簡介
現在的rust生態中,async/await在rust1.39中已經stable,其他庫還有futures 已經到0.3.x,還有就是本次說的這個async-std,async-std主要使用的就是標準庫中的Future,它也會依賴futures庫,包含futures庫中的一些特性,其實標準庫中的Future也是移植了futures庫中的Future.
async/await
async和await是可以分開的兩個術語,分開理解(針對Rust語言的,其他語言就很不一樣)
- async:產生一個Future物件,一個沒有任何作用的物件,必須由呼叫器呼叫才會有用
- await: 等待非同步操作完成(基於語義理解,其實很多情況只有呼叫future.await才是事實上去呼叫,具體是不是之前就開始執行,這個要看我們的呼叫器是什麼),這步是阻塞當前執行緒,這個語法屬於Future物件才能呼叫,而且必須要在async函式內
這列出三個非同步基礎作用
- 延遲計算:不需要立即得到結果
- 併發:多個操作併發執行,像多執行緒執行操作
- 獨立性:(暫時不理解)
async語法
1.在函式前新增async關鍵字
async fn async_test(){
println!("hello async");
}
2:async閉包
async || {
println!("hello async");
}
3: async move
fn async_test() -> impl Future<Output =Result<(),String>>{
async move {
println!("hello async");
Ok(())
}
}
再次提醒:帶有async關鍵字的函式直接呼叫是沒有任何作用的,比如下面的呼叫 async_test();不會列印任何東西
Future
上面說的三種,都會生成一個Future,看看Futrue定義
pub trait Future {
type Output;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
}
執行器(task executor)
把task放到這來說,就把它理解為Future就是我們要做任務的一個細節描述,task呢就是這些根據這些細節描述去做,下面就是怎麼做的一些具體實現
block_on:阻塞呼叫,會阻塞當前執行緒直到有結果返回
spawn : 非同步併發呼叫,類似多執行緒同時呼叫,這個函式會返回 JoinHandle,
例子
待補充
檔案
use async_std::{
fs::File, // 支援非同步操作的檔案結構體
task, // 呼叫排程器
prelude::* // Future或輸入輸出流
};
fn main() {
// 阻塞執行Future
task::block_on(file_test());
}
/// 讀取一個檔案中的64個位元組(十進位制表示)
async fn file_test() ->Result<(), std::io::Error>{
let mut file = File::open("d:\\ABC.txt").await?;// ?號表示如果Err,會直接返回
let mut buffer:[u8; 64] = [0; 64];// 建立一個64個長度的位元組陣列
let n = file.read(&mut buffer).await?; // 每個await都是阻塞
println!("The bytes: {:?}", &buffer[..n]);
Ok(())
}
網路
待補充
結束語
從java轉過來的,有可能對async/await這個特性比較混亂,java中的Future非同步就是多執行緒呼叫,在rust中的Future又要複雜些
本作品採用《CC 協議》,轉載必須註明作者和本文連結