生命周期的文章研究了不少,大概是因为本人确实愚钝,还是没有解决这个问题,求大佬来指条明路,万分感谢
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
trait ReadFromFile {
fn read_from_file<'a, T: Serialize>(path: &PathBuf) -> T
where
T: Deserialize<'a>
{
let v = std::fs::read_to_string(path).unwrap();
serde_json::from_str(&v).unwrap()
}
}
#[derive(Serialize, Deserialize, Debug)]
struct Server {
username: String,
password: String
}
#[derive(Serialize, Deserialize, Debug)]
struct Servers {
servers: Server
}
impl ReadFromFile for Server {}
impl ReadFromFile for Servers {}
fn main() {
let path = PathBuf::from("./servers.json");
let _servers:Servers = Servers::read_from_file(&path);
println!("hello");
}
playground的地址如下:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=c94374bf27901541074821bf37dec401
1
共 7 条评论, 1 页
评论区
写评论#[cfg(test)] mod tests { use std::path::PathBuf;
}
你太客气了,还特意去看了一下,因为之前只是简单的用Serialize/Deserialize, 所以也没有想到引入DeserializeOwned
我再多去看一下,收获很多,再次感谢!
--
👇
Aya0wind: 不好意思,我又去试了一下,应该还是你生命周期标记的问题,直接使用from_str从String反序列化一个类型是会copy的。只是from_reader由于没有buffer效率较低,才会需要一个bufferreader。
所以问题并不在from_str,from_str是可以的,而是你把'a生命周期绑定到T上了,但是这里根本不需要’a,因为返回的T本身是不引用那个字符串v的,所以你应该这么写。
--
👇
Nayaka: 十分感谢,刚刚参考 @Aya0wind 的回答,已经搞定了. 看了你的答案,对生命周期有了新的理解,再次感谢!
--
👇
Grobycn: 改成这样可以通过,可以理解为对于所有可能的生命周期
'a
, 都可以反序列化出一个T
,T
已经不依赖于输入参数的生命周期'a
了。不好意思,我又去试了一下,应该还是你生命周期标记的问题,直接使用from_str从String反序列化一个类型是会copy的。只是from_reader由于没有buffer效率较低,才会需要一个bufferreader。
所以问题并不在from_str,from_str是可以的,而是你把'a生命周期绑定到T上了,但是这里根本不需要’a,因为返回的T本身是不引用那个字符串v的,所以你应该这么写。
--
👇
Nayaka: 十分感谢,刚刚参考 @Aya0wind 的回答,已经搞定了. 看了你的答案,对生命周期有了新的理解,再次感谢!
--
👇
Grobycn: 改成这样可以通过,可以理解为对于所有可能的生命周期
'a
, 都可以反序列化出一个T
,T
已经不依赖于输入参数的生命周期'a
了。十分感谢,刚刚参考 @Aya0wind 的回答,已经搞定了. 看了你的答案,对生命周期有了新的理解,再次感谢!
--
👇
Grobycn: 改成这样可以通过,可以理解为对于所有可能的生命周期
'a
, 都可以反序列化出一个T
,T
已经不依赖于输入参数的生命周期'a
了。改成这样可以通过,可以理解为对于所有可能的生命周期
'a
, 都可以反序列化出一个T
,T
已经不依赖于输入参数的生命周期'a
了。之前想过from_reader,结果还是跟from_str杠上了,谢谢
--
👇
Aya0wind: 你看一下serde_json的文档,文档里提到:
所以serde_json的from_str是直接在输入的str上原地构造的,所以你引用一个局部的String,返回之后String就没了,所以你返回反序列化的结果就指向无效内存了。
至于正确写法,serde_json的文档里有一个和你这个功能一模一样的例子,你可以看看应该怎么做 serde_json::from_reader
你看一下serde_json的文档,文档里提到:
所以serde_json的from_str是直接在输入的str上原地构造的,所以你引用一个局部的String,返回之后String就没了,所以你返回反序列化的结果就指向无效内存了。
至于正确写法,serde_json的文档里有一个和你这个功能一模一样的例子,你可以看看应该怎么做 serde_json::from_reader