serde_json 将 String 转换为具有生命周期注释的类型会导致问题

问题描述 投票:0回答:1
pub async fn checkin_seed_node<'a>(appstate: Arc<AppState<'a>>) {
    loop {
        let response: Response = call_seed_node(&appstate.client).await;
        let body = response
            .text()
            .await
            .expect("failed to get text from response");
        // &body causes borrow issues.
        let nodes: Vec<Node<'_>> =
            serde_json::from_str(&body.as_str()).expect("failed to parse response");

        for node in &nodes {
            let mut lock = appstate.internal.lock();
            let mut map = lock.borrow_mut();
            map.insert(
                100,
                Node {
                    address: node.address,
                },
            );
        }
    }
}

// using reqwest client call an endpoint
async fn call_seed_node(client: &Client) -> Response {
    time::sleep(time::Duration::from_secs(2)).await;
    let response = client
        .get("http://localhost:8080/node-config")
        .send()
        .await
        .expect("failed to get a response");
    response
}

// Node struct
pub struct Node<'a> {
    pub address: &'a str,
}

impl<'a> Node<'a> {
    pub fn new(address: &'a str) -> Self {
        Node { address }
    }
}

当我尝试编译这段代码时,我遇到了以下编译错误。

error[E0597]: `body` does not live long enough
  --> src/lib.rs:20:35
   |
   |   pub async fn checkin_seed_node<'a>(appstate: Arc<AppState<'a>>) {
   |                                      -------- lifetime `'1` appears in the type of `appstate`
...
   |               serde_json::from_str(&body.as_str()).expect("failed to parse response");
   |                                     ^^^^^^^^^^^^^ borrowed value does not live long enough
...
   | /             map.insert(
   | |                 100,
   | |                 Node {
   | |                     address: node.address,
   | |                 },
   | |             );
   | |_____________- argument requires that `body` is borrowed for `'1`
   |           }
   |       }
   |       - `body` dropped here while still borrowed

For more information about this error, try `rustc --explain E0597`.

我是 Rust 的新手,所以这是我第一次处理生命周期注解。我尝试使用 Box,希望将数据推送到堆上可能会有所帮助,但我遇到了同样的问题。

rust lifetime borrow-checker serde-json
1个回答
0
投票

反序列化为借用的字符串切片绝对不是您想要的,例如像这样反序列化 JSON 将失败:

fn main() {
    let s = r#""hello\"world""#;
    let st: &str = serde_json::from_str(s).unwrap();
}

因为不修改字符串就无法反序列化包含转义序列的字符串。

此外,您需要拥有

address
的东西,老实说,最好的存储位置就是
Node
所以解决方法是根本不借用
Node
中的数据:

#[derive(serde::Deserialize)]
struct Node {
    address: String,
}
© www.soinside.com 2019 - 2024. All rights reserved.