use std::error::Error;
use futures::executor::block_on;
async fn fetch_data() -> Result<String, Box<dyn Error>> {
// 模拟网络请求获取数据
Ok("example data".to_string())
}
async fn process_data(data: String) -> Result<String, Box<dyn Error>> {
// 模拟数据处理
Ok(data.to_uppercase())
}
fn main() {
let result = block_on(async {
let data = fetch_data().await?;
let processed_data = process_data(data).await?;
Ok::<String, Box<dyn Error>>(processed_data)
});
match result {
Ok(data) => println!("Processed data: {}", data),
Err(e) => eprintln!("Error: {}", e),
}
}
move关键字与async
/await
机制协同工作说明
- 所有权转移:在Rust中,变量的所有权是其核心概念。当我们在
async
函数中使用move
关键字时,例如let data = fetch_data().await?;
,fetch_data
返回的Result<String, Error>
中的String
的所有权被转移到data
变量。然后我们将data
传递给process_data
函数,data
的所有权又转移到process_data
函数内。这样保证了每个阶段对数据的唯一拥有权,避免了数据竞争和悬空指针等问题。
- 异步执行模型:
async
函数返回一个Future
,它在执行到await
点时会暂停,将执行权交回给调用者。在这个过程中,move
关键字确保了即使异步函数暂停执行,其内部捕获的变量(例如data
)的所有权也能被正确管理。当异步函数恢复执行时,它仍然拥有之前捕获变量的所有权,能够继续操作这些变量。
- 内存安全:通过
move
关键字与async
/await
机制的协同工作,Rust保证了在异步编程中内存的安全。在await
点,async
函数内部的状态被保存,而move
关键字确保了这些状态中涉及的变量所有权被正确处理。这使得Rust的异步编程既高效又安全,避免了像其他语言中可能出现的内存泄漏和数据竞争等问题。