use of moved value: `response` value used here after move for types not implementing the Copy trait

huangapple go评论65阅读模式
英文:

use of moved value: `response` value used here after move for types not implementing the Copy trait

问题

以下是翻译好的部分:

我有这段代码,它抛出以下错误:use of moved value: response value used here after move

错误来自于 response_body 变量使用了 response 变量并占用了它的所有权。我想要克隆 response,或者将提取键(execution_id)的操作封装在一个函数中,并传递 response 的引用,但都没有成功。

我应该实现 Clone 或 Copy 特性,但无法为未在 crate 中定义的结构体实现它们。所以我不知道如何处理这种情况。

如何消除这个错误?谢谢。

英文:

I have this code which is throwing the following error: use of moved value: response value used here after move.

use std::collections::HashMap;
use reqwest::Response;
use serde_json::json;

async fn error_example() -> (Response, String) {
    let execute_url = "https://jsonplaceholder.typicode.com/todos/1";

    let client = reqwest::Client::new();

    let response = client.post(execute_url).send().await.unwrap();

    let response_body = response.text().await.unwrap();
    let response_body: HashMap<String, String> = serde_json::from_str(&response_body).unwrap();
    let execution_id = response_body.get("userId").unwrap();

    return (response, execution_id.clone()); // use of moved value: `response` value used here after move
}

The error come from the response_body variable using the response variable and taking ownership of it. I wanted to clone the response, or wrap the extraction of the key (execution_id) in a function and passing a ref of the response but none worked.

I should have the Clone or Copy trait implemented but I can't implement it for struct not defined within the crate. So I don't know how to handle this case.

How can I get rid of the error ? Thanks

答案1

得分: 2

Reqwest的Response类型实际上并不包含响应体。它基本上是一个开放的网络套接字,加上接受数据所需的状态。当你调用text时,它直接从套接字构建一个String。如果你想再次调用text,你需要重新发送请求,因为Response和套接字都不存储这些数据。

所以如果你想返回整个请求体,你可以返回刚刚创建的字符串。

let response_body = response.text().await.unwrap();
let response_map: HashMap<String, String> = serde_json::from_str(&response_body).unwrap();
let execution_id = response_map.get("userId").unwrap().clone();

(response_body, execution_id)

或者你可以返回头部、状态码或任何其他你需要的内容。Reqwest没有一种类型来表示已使用的响应,但你可以自己创建一个。


另一件事是,不必反序列化整个响应。你可以为只需要的字段创建一个结构体,这意味着你只需要分配一个String,而且不需要克隆它。

#[derive(serde::Deserialize)]
#[serde(rename_all = "camelCase")]
struct OnlyUserId {
    user_id: String
}

let only_user_id: OnlyUserId = serde_json::from_str(&response_body).unwrap();
let execution_id = only_user_id.user_id;

(response_body, execution_id)
英文:

Reqwest's Response type does not really contain the response body. It's basically an open network socket plus the state needed to accept the data. When you call text, it builds a String straight from the socket. If you wanted to call text again, you'd need to resend the request, since neither Response nor the socket store this data.

So if you want to return the whole request body, you can return the string that was just created.

let response_body = response.text().await.unwrap();
let response_map: HashMap&lt;String, String&gt; = serde_json::from_str(&amp;response_body).unwrap();
let execution_id = response_map.get(&quot;userId&quot;).unwrap().clone();

(response_body, execution_id)

Or you could return the headers, or status code, or whatever else you need. Reqwest doesn't have a type to represent a spent response, but you could make your own.


Another thing is that deserializing the entire response is not necessary. You can make a struct for just the field you need, which means you only need to allocate one String, and you don't need to clone it.

#[derive(serde::Deserialize)]
#[serde(rename_all = &quot;camelCase&quot;)]
struct OnlyUserId {
    user_id: String
}

let only_user_id: OnlyUserId = serde_json::from_str(&amp;response_body).unwrap();
let execution_id = only_user_id.user_id;

(response_body, execution_id)

huangapple
  • 本文由 发表于 2023年6月13日 08:23:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/76461012.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定