生成问题serde_json读入“Vec<T>”(锈)[重复]

Problem generify-ing serde_json read into a `Vec<T>` (rust) [duplicate]

提问人:John Graham 提问时间:11/12/2023 更新时间:11/12/2023 访问量:45

问:

我有几个 JSON 文件,在顶层,它们只是具有不同类型数据的数组,所以最好有一个以通用方式处理这个问题的函数。

这是我到目前为止所拥有的(rust playground 链接):

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

我能做些什么来解决这个问题?

generics rust lifetime serde-json

评论

4赞 user4815162342 11/12/2023
只要换成(并摆脱生命),好事就会发生。完全绑定支持高级零拷贝用法,在这种情况下不需要(也不能使用)。Deserialized<'a>DeserializeOwnedDeserialize<'a>
0赞 John Graham 11/12/2023
这似乎已经成功了 - 谢谢!
0赞 user4815162342 11/12/2023
我想将其标记为重复,但不知何故,我无法找到一个非常清楚地说明这一点的问题(和答案)。
1赞 Chayim Friedman 11/13/2023
@user4815162342 我认为找到了一个很好的副本。

答:

2赞 user4815162342 11/12/2023 #1

由于错误消息以一种非常不透明的方式暗示,因此您需要更改为 ,并省略生存期。这样一来,你的代码就可以编译并做你想做的事了: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