我有几个 JSON 文件,它们在顶层只是具有不同类型数据的数组,因此最好有一个函数以通用方式处理此问题。
这是我到目前为止所拥有的(rust游乐场链接):
use std::path::Path;
use std::fs::File;
use std::io::BufReader;
use serde::Deserialize;
fn get_json<'a, T: Deserialize<'a>>(path: &Path) -> Vec<T> {
let file = File::open(path).unwrap();
let reader = BufReader::new(file);
let sentences: Vec<T> = serde_json::from_reader(reader).unwrap();
sentences
}
我真的不明白它给出的错误,或者我如何说服借用检查器一切都很好:
Compiling playground v0.0.1 (/playground)
error: lifetime may not live long enough
--> src/lib.rs:10:29
|
6 | fn get_json<'a, T: Deserialize<'a>>(path: &Path) -> Vec<T> {
| -- lifetime `'a` defined here
...
10 | let sentences: Vec<T> = serde_json::from_reader(reader).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
note: due to current limitations in the borrow checker, this implies a `'static` lifetime
--> /playground/.cargo/registry/src/index.crates.io-6f17d22bba15001f/serde_json-1.0.107/src/de.rs:2591:8
|
2591 | T: de::DeserializeOwned,
| ^^^^^^^^^^^^^^^^^^^^
error: implementation of `Deserialize` is not general enough
--> src/lib.rs:10:29
|
10 | let sentences: Vec<T> = serde_json::from_reader(reader).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Deserialize` is not general enough
|
= note: `Vec<T>` must implement `Deserialize<'0>`, for any lifetime `'0`...
= note: ...but it actually implements `Deserialize<'1>`, for some specific lifetime `'1`
error: could not compile `playground` (lib) due to 2 previous errors
我可以做什么来解决这个问题?
由于错误消息以非常不透明的方式提示,您需要将
Deserialized<'a>
更改为 DeserializeOwned
(并摆脱生命周期)。这一更改使您的代码可以编译并执行您想要的操作:
fn get_json<T: DeserializeOwned>(path: &Path) -> Vec<T> {
let file = File::open(path).unwrap();
let reader = BufReader::new(file);
serde_json::from_reader(reader).unwrap()
}
如果您好奇,当您需要零拷贝反序列化时,完整的
Deserialize<'a>
边界非常有用,反序列化数据指向创建它的反序列化源。在你的情况下,这既不需要也不想要,所以 DeserializeOwned
正是你想要的。请参阅文档了解更多详情。