Reqwest Cookies 的 impl 迭代器中项目的生命周期

问题描述 投票:0回答:1

问题的标题可能没有抓住这个问题的本质,我很乐意进行编辑。

我刚刚开始用 Rust 写作,正在编写一个小程序来学习

Rust
和包
Reqwest

这是我的小程序。我不明白为什么从

HashMap<&str, &str>
更改为
HashMap<String, String>
可以使其工作,而 cookie 仍然只存在于范围内?我也在代码中评论了我的疑问。

use reqwest::cookie::Jar;
use reqwest::{Client, Url};
use std::sync::Arc;
use std::collections::HashMap;

#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
    let jar = Jar::default();
    let raw_url = "https://www.google.com";

    let url = Url::parse("https://www.google.com").unwrap();
    jar.add_cookie_str("session=1", &url);

    let jar = Arc::new(jar);
    let client_builder = Client::builder();

    let client = client_builder
                   .cookie_provider(Arc::clone(&jar))
                   .build()?;

    let response = client.get(raw_url).send().await?;

    let headers: &HeadersMap = response.headers();

    let cookies: Impl Iterator<Item=Cookie>+Sized = response.cookies();


    // let mut cookie_map = HashMap::<String, String>::new(); // this would work;

    let mut cookie_map = HashMap::<&str, &str>::new(); // impl<'a> Cookie<'a>

    let mut header_map = HashMap::<&str, &str>::new(); // live as long as the programme

    for cookie in cookies { // declared borrowed value here, hence the lifetime kicks in
         // Error: cookie does not live long enough
         cookie_map.insert(cookie.name(), cookie.value());

         // cookie_map.insert(cookie.name().to_string(), cookie.value().to_string());
         // with `to_string` we have taken ownership of the value; is this why it's working?
    }
    // cookie dropped while still borrowed here;
    // kv pairs are both borrowed values that have a lifetime `'a` which ends here
    // and cookie_map apparently continues to exist, hence the error (this is my guess)
    

    for (k, v) in headers.iter() {
         match v.to_str() {
             Ok(val) => header_map.insert(k.as_str(), val),
             Err(_) => panic!()
         };
    }
    

    for (hk, kv) in header_map {
         println!("header name is {}, header value is {}", hk, kv);
    }

    Ok(())
}

这是

cargo.toml

[package]
name = "tester"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[[bin]]
name = "tester"
test = false
bench = false

[dependencies]
reqwest = { version = "0.11", features = ["blocking", "json", "cookies"] }
tokio = { version = "1", features = ["full"] }
futures = "0.3"
reqwest_cookie_store = "0.7.0"

我已经在节目中评论了我的疑惑。

根据要求,这里提供了

cargo check
错误日志。


error[E0597]: `cookie` does not live long enough
  --> src/tools/fetcher.rs:32:32
   |
31 |          for cookie in cookies {
   |              ------ binding `cookie` declared here
32 |              cookie_map.insert(cookie.name(), cookie.value());
   |              ----------        ^^^^^^ borrowed value does not live long enough
   |              |
   |              borrow later used here
33 |          }
   |          - `cookie` dropped here while still borrowed

For more information about this error, try `rustc --explain E0597`.
error: could not compile `data_fetcher` (bin "data_fetcher") due to 1 previous error


rust ownership reference-lifetimes
1个回答
0
投票

cookie
仅在循环的一次迭代期间存在。
&str
是对字符串的引用,因此引用的值必须至少与引用所在的
HashMap
一样长。但是由于
cookie
在迭代后被销毁,因此该值会丢失。

解决方案是取得

&str
的所有权。这就是您通过将类型更改为
String
所做的事情。

© www.soinside.com 2019 - 2024. All rights reserved.