Rust使用reqwest解析JSON时共享引用后*response无法移出问题求助
问题解决:reqwest响应的所有权与借用冲突
错误原因
你给response加了共享引用&,但reqwest::Response的json()方法需要获取响应的所有权(因为解析过程会消耗响应体),共享引用下无法转移所有权,所以触发了cannot move out of *response which is behind a shared reference错误。
修复步骤
- 去掉response的引用,直接持有Response实例的所有权
- 替换错误处理方法:用
error_for_status()替代error_for_status_ref(),前者针对拥有所有权的Response,会在无错误时返回自身的所有权,方便后续调用json()
修复后的完整代码
#[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct MessagesListResponse{ messages: Vec<MessageId> } #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct MessageId{ id: String, thread_id: String } #[async_trait] impl MessageGetter for GmailMessageGetter{ async fn get_message_ids(&self) -> Vec<String> { let url = "https://gmail.googleapis.com/gmail/v1/users/me/messages?q=from%3Awebank%40webank.it%20subject%3Aautorizzato%20pagamento".to_owned(); dbg!(&url); // 去掉引用,直接获取Response所有权 let mut response = self.client.get(url).send().await.unwrap(); // 使用error_for_status()获取无错误的Response所有权 response = response.error_for_status().unwrap(); // 现在可以正常调用json(),因为我们拥有response的所有权 let msg_list_response = response.json::<MessagesListResponse>().await.unwrap(); msg_list_response.messages.into_iter().map(|message_id| message_id.id).collect() } }
补充说明
reqwest::Response::json()的方法签名是async fn json<T: DeserializeOwned>(self) -> Result<T, Error>,参数是self(而非&self),意味着它会拿走Response的所有权——因为解析JSON需要读取响应体的全部字节,读取完成后响应体就被消耗了,无法再重复使用。你之前用引用的方式,相当于只拿到了响应的“使用权”,没办法把所有权移交给json()方法,自然就报错了。
内容的提问来源于stack exchange,提问作者exrezzo
相关产品推荐
相关产品推荐

