首页 > 解决方案 > 我应该如何在 rust 中获取该对象的副本?

问题描述

我有一个小程序,它应该打印出 html 获取请求的响应状态,并打印出该响应的原始 html。(我为此使用了最新版本的 reqwest crate)

fn main() {
    let req = reqwest::blocking::get("https://www.rust-lang.org");
    let rawhtml = req.clone().unwrap().text().unwrap();
    let status = req.unwrap().status();

    println!("status: {}\n\n", status);
    println!("{}", rawhtml);
}

运行cargo run给我错误[E0599]说

Result<reqwest::blocking::Response, reqwest::Error>由于不满足的特征界限,无法调用方法

因此,如果我无法克隆该对象,那么我如何使用多个消耗“自我”的功能?当我需要的所有信息都应该放在一个时,我不想发出多个获取请求。

标签: rustcopy

解决方案


首先,reqwest::blocking::Response没有实现Clone或提供替代方案,因此“获取副本”不是一种选择;你需要构建你的程序,所以它不需要副本。

您当前代码遇到的问题主要不在于Response; 是你正在调用的Result::unwrap,它确实消耗了Result它被调用的东西——为了给你它的内容。正确的做法是只调用unwrap一次。

    let req = reqwest::blocking::get("https://www.rust-lang.org")
        .unwrap();
    let rawhtml = req.text().unwrap();
    let status = req.status();

这仍然无法编译,但那是因为您以错误的顺序调用方法:在使用body之前,您必须从响应的标头中询问您需要的任何内容。这不是一个任意的约束;这是因为 HTTP 以该顺序为您提供该信息,因此让 API 以这种方式工作允许在下载响应时不需要存储整个响应 - 该对象不仅仅是一个不变的数据结构,而且实际上代表了响应。正在发送到您的计算机。reqwestResponse

此版本将工作:

    let req = reqwest::blocking::get("https://www.rust-lang.org")
        .unwrap();
    let status = req.status();
    let rawhtml = req.text().unwrap();

status并且rawhtml两者都实现Clone,因此您可以保留它们并根据需要制作副本,这与Response.

(免责声明:我并没有真正使用过reqwest自己;这个答案是基于阅读文档和源代码,以及一般的 Rust 原则。)


推荐阅读