You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust使用reqwest解析JSON时共享引用后*response无法移出问题求助

问题解决:reqwest响应的所有权与借用冲突

错误原因

你给response加了共享引用&,但reqwest::Response的json()方法需要获取响应的所有权(因为解析过程会消耗响应体),共享引用下无法转移所有权,所以触发了cannot move out of *response which is behind a shared reference错误。

修复步骤

  1. 去掉response的引用,直接持有Response实例的所有权
  2. 替换错误处理方法:用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 10:57:32