我有几个JSON文件,它们在顶层只是包含不同类型数据的数组,所以如果有一个函数以通用的方式处理这一问题就好了.

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

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()
}

Playground

当您需要零拷贝数据化时,完整的Deserialize<'a>绑定非常有用,其中数据化的数据可以指向它被数据化的源.在你的情况下,这既不可能也不希望,所以DeserializeOwned正是你想要的.看the docs更多的deails.

Rust相关问答推荐

移植带有可变borrow 的C代码-卸载期间错误(nappgui示例)

即使参数和结果具有相同类型,fn的TypId也会不同

如何从Rust记录WASM堆内存使用情况?

在泛型 struct 的字段声明中访问关联的Conant

值为可变对象的不可变HashMap

rust 迹-内存管理-POP所有权-链表

你是如何在铁 rust 一侧的金牛座获得应用程序版本的?

自定义结果枚举如何支持`?`/`FromResidual`?

为什么RefCell没有与常规引用相同的作用域?

Windows 上 ndarray-linalg 与 mkl-stats 的链接时间错误

为什么实现特征的对象期望比具体对象有更长的生命周期?

借来的价值生命周期 不够长,不确定为什么它仍然是借来的

`use` 和 `crate` 关键字在 Rust 项目中效果不佳

(let b = MyBox(5 as *const u8); &b; ) 和 (let b = &MyBox(5 as *const u8); ) 之间有什么区别

在 Bevy 项目中为 TextureAtlas 精灵实施 NearestNeighbor 的正确方法是什么?

`移动||异步移动{...}`,如何知道哪个移动正在移动哪个?

Rust 中 `Option` 的内存开销不是常量

判断 is_ok 后重用结果

在 RefCell 上borrow

当值是新类型包装器时,对键的奇怪 HashMap 生命周期要求