【问题标题】:In Rust, how to push an object with a lifetime into a vector?在 Rust 中,如何将具有生命周期的对象推送到向量中?
【发布时间】:2020-03-25 17:38:35
【问题描述】:

我的代码有点类似于以下内容,它尝试从 websocket 中读取数据,将 JSON 结果解析为结构,然后将该结构推送到 Vec 缓冲区。然而,代码无法编译,因为结构有生命周期,并且借用检查器抱怨 JSON 字符串的生命周期不够长。

use serde::{Deserialize, Serialize};
use tungstenite::client::AutoStream;
use tungstenite::protocol::WebSocket;

#[derive(Serialize, Deserialize, Debug, Clone)]
struct MyType<'a> {
    id: &'a str,
    count: i64,
}

fn example<'a>(
    conn: &mut WebSocket<AutoStream>,
    buff: &'a mut Vec<MyType<'a>>,
) -> Option<Box<dyn std::error::Error>> {
    match conn.read_message() {
        Err(err) => Some(err.into()),
        Ok(msg) => {
            let resp_raw = msg.to_string();
            let resp_parsed: Result<MyType<'a>, _> = serde_json::from_str(&resp_raw);
            match resp_parsed {
                Err(err) => Some(err.into()),
                Ok(resp) => {
                    buff.push(resp.clone());
                    None
                }
            }
        }
    }
}

确切的错误是borrowed value [&amp;resp_raw] does not live long enough

我想知道我应该如何重组这段代码以满足借用检查器的要求;将具有生命周期的结构推送到 Vec 参数的正确方法是什么?

还是&amp;'a str解析成MyType实际上仍然保留对原始JSON字符串的引用,所以没有办法安全地这样做?

【问题讨论】:

  • 您为什么使用&amp;str 代替id?如果它是一个引用,那么 ID 需要由其他东西拥有,但是您的代码专门从一个 strong 创建一个结构,然后丢弃该字符串,因此没有任何东西会拥有该 ID。 id 可以改为String 吗?
  • 您能粘贴一个有效的操场链接(不依赖于 tungstenite)吗?

标签: rust lifetime borrow-checker lifetime-scoping


【解决方案1】:

仔细看serde_json::from_str

pub fn from_str<'a, T>(s: &'a str) -> Result<T> 
where
    T: Deserialize<'a>, 

这表示反序列化的T 与输入s 共享相同的生命周期。这允许零拷贝反序列化,这就是你在MyType 中得到的,其中id 是对字符串切片的引用。这将MyType 的生命周期绑定到&amp;resp_raw 的生命周期,fn example() 是本地的。这行不通。

不能通过给buff 提供你给它的生命周期参数来解决这个问题。 example-function 拥有MyType 指向的缓冲区。允许MyType“逃逸”到Vec 将允许创建悬空引用,因为一旦example 返回,缓冲区就会被销毁。

MyType改为满足DeserializeOwned,即不带lifetime参数。您需要String 或(为了节省一点记忆)Box&lt;str&gt; 而不是&amp;str

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-07
    • 2013-07-03
    • 2015-04-01
    • 2014-09-10
    • 2021-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多