在 Rust 中,如何将具有生命周期的对象推送到向量中?



我的代码有点像下面,它尝试从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 [&resp_raw] does not live long enough.

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

或者解析为MyType&'a str实际上仍然保留对原始 JSON 字符串的引用,因此无法安全地执行此操作?

仔细看看serde_json::from_str

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

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

这个问题不能通过给buff你给它的生存期参数来解决。example函数拥有MyType指向的缓冲区。允许MyType"逃逸"到Vec中将允许创建悬空引用,因为缓冲区一旦返回example就会被破坏。

更改MyType以满足DeserializeOwned,即不采用生命周期参数。您需要一个String或一个(为了保护一点记忆(一个Box<str>而不是一个&str

相关内容

  • 没有找到相关文章

最新更新