Rust链式调用收集Vec<&Post>报错E0716的原因解析
Rust临时值被释放错误(E0716):链式调用vs分步调用的差异解析
刚学习Rust,尝试从模拟API获取并反序列化Post结构体的Vec,分两步编写代码可正常运行,但将操作链式整合后出现E0716错误(临时值被释放仍被借用),无法理解两种写法的差异及错误原因。
正常运行的代码
use serde::{Deserialize, Serialize}; #[derive(Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] struct Post { user_id: i32, id: i32, title: String, body: String, } #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { let posts = reqwest::get("https://jsonplaceholder.typicode.com/posts") .await? .json::<Vec<Post>>() .await?; let posts = posts .iter() .map(|post| post) .collect::<Vec<&Post>>(); println!("{:#?}", posts); Ok(()) }
报错的链式调用代码
#[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { let posts = reqwest::get("https://jsonplaceholder.typicode.com/posts") .await? .json::<Vec<Post>>() .await? .iter() .map(|post| post) .collect::<Vec<&Post>>(); println!("{:#?}", posts); Ok(()) }
错误信息
error[E0716]: temporary value dropped while borrowed --> src/lib.rs:15:17 | 15 | let posts = reqwest::get("https://jsonplaceholder.typicode.com/posts") | _________________^ 16 | | .await? 17 | | .json::<Vec<Post>>() 18 | | .await? | |_______________^ creates a temporary value which is freed while still in use ... 21 | .collect::<Vec<&Post>>(); | - temporary value is freed at the end of this statement ... 24 | println!("{:#?}", posts); | ----- borrow later used here | = note: consider using a `let` binding to create a longer lived value
原因解析
核心差异:临时值的生命周期
两种写法的本质区别在于拥有所有权的Vec<Post>的生命周期:
分步写法:
- 第一行
let posts = ...将反序列化得到的Vec<Post>绑定到了变量posts上,这个变量的生命周期贯穿整个main函数剩余部分。 - 后续调用
posts.iter()生成的引用,生命周期和posts完全一致。收集成Vec<&Post>后,这些引用指向的原Vec<Post>依然存活,所以引用始终有效。
- 第一行
链式写法:
.json::<Vec<Post>>().await?返回的Vec<Post>是一个临时值,没有被绑定到任何变量。Rust中临时值的生命周期仅局限于当前语句(即到末尾的;为止)。- 你通过
iter()获取了这个临时Vec<Post>的引用,并收集成Vec<&Post>。当语句结束,临时Vec<Post>会被立即销毁,导致posts中的所有引用都变成了悬空引用——指向已经被释放的内存,因此编译器抛出E0716错误。
解决思路
- 最直接的方式就是像分步写法那样,先将拥有所有权的
Vec<Post>绑定到变量,确保其生命周期覆盖引用的使用范围。 - 如果不需要引用,也可以直接使用原
Vec<Post>,或者通过clone()生成新的Vec<Post>(而非引用集合),避免依赖临时值的生命周期。
内容的提问来源于stack exchange,提问作者Odiumediae
相关产品推荐
相关产品推荐

