Rust 使用Box实现结构的反序列化
包含框作为成员变量的结构: 类型项目=dyn Fn->结果; 结构内部{ 发布数据:框, } //函数,如类型:Item fn解析->结果{ println!调用parse; 好啊 } 现在出现了一个问题,即自定义为结构内部实现反序列化以反序列化:Rust 使用Box实现结构的反序列化,rust,deserialization,serde,serde-json,Rust,Deserialization,Serde,Serde Json,包含框作为成员变量的结构: 类型项目=dyn Fn->结果; 结构内部{ 发布数据:框, } //函数,如类型:Item fn解析->结果{ println!调用parse; 好啊 } 现在出现了一个问题,即自定义为结构内部实现反序列化以反序列化: let s = r#"{"data": "parse"}"#; 进入结构内部: { data: Box::new(parse) } 我知道serde没有为Box实现反序列化,并且
let s = r#"{"data": "parse"}"#;
进入结构内部:
{
data: Box::new(parse)
}
我知道serde没有为Box实现反序列化,并且必须手动实现反序列化,下面是我的代码,如下示例所示:
使用serde::de::{self,反序列化,反序列化器,MapAccess,Visitor};
使用std::fmt;
类型项目=dyn Fn->结果;
结构内部{
发布数据:框,
}
fn解析->结果{
println!调用parse;
好啊
}
内隐{
fn反序列化反序列化器:D->Result
哪里
D:反序列化程序反序列化,
{
结构域访问者;
现场访客的impl{
类型值=字段;
fn预期&self,格式化程序:&mut fmt::格式化程序->fmt::结果{
格式化程序。仅写入'data'
}
fn访问\u strself,值:&str->Result
哪里
E:de::错误,
{
匹配值{
data=>OkField::data,
_=>Errde::Error::未知的\u字段值,字段,
}
}
}
反序列化器。反序列化\u标识符字段查看器
}
}
结构内部访问者;
InnerVisitor的impl{
类型值=内部;
fn预期&self,格式化程序:&mut fmt::格式化程序->fmt::结果{
格式化程序.write\u struct内部
}
fn访问\u mapself,mut map:V->结果
哪里
V:MapAccess警告给了您一个提示:您没有使用数据,所以Rust不关心选项中的类型。实际上,我很惊讶它正在编译。Rust假设您期望,因为serdes默认类型,而您期望的是字符串。您的数据根本没有被使用,所以只需执行以下操作: 让mut数据:选项=无; 此外,我建议将所有现场实施替换为: [衍生产品系列化] [serdefield_标识符,重命名_all=小写] 枚举字段{ 数据 } 不知什么原因,这个堆栈会溢出,但我想这是游乐场的问题 此外,您还可以使用: 使用serde::{反序列化,反序列化程序}; 类型项目=dyn Fn->结果; [衍生产品系列化] 结构内部{ [serdedeserialize_with=反序列化_数据] 发布数据:框, } fn反序列化_数据, { 让数据=::反序列化?; println!{},数据; OkBox::newparse } fn解析->结果{ println!调用parse; 好啊 } fn干线{ 设s=r{data:parse}; 让inner:inner=serde_json::from_strs.unwrap; }
这要好得多,因为serde宏的实现可以比简单的实现更好地编写代码。警告给了您一个提示:您没有使用数据,所以Rust不关心选项中的类型。事实上,我很惊讶它正在编译。Rust假设您期望,因为serde默认类型,而您期望String.您的数据根本没有被消耗,因此只需执行以下操作: 让mut数据:选项=无; 此外,我建议将所有现场实施替换为: [衍生产品系列化] [serdefield_标识符,重命名_all=小写] 枚举字段{ 数据 } 不知什么原因,这个堆栈会溢出,但我想这是游乐场的问题 此外,您还可以使用: 使用serde::{反序列化,反序列化程序}; 类型项目=dyn Fn->结果; [衍生产品系列化] 结构内部{ [serdedeserialize_with=反序列化_数据] 发布数据:框, } fn反序列化_数据, { 让数据=::反序列化?; println!{},数据; OkBox::newparse } fn解析->结果{ println!调用parse; 好啊 } fn干线{ 设s=r{data:parse}; 让inner:inner=serde_json::from_strs.unwrap; }
这是更好的方法,因为serde宏的实现可以比简单的实现更好地编写代码。Stargateurs的一个类似技巧是在内部类上使用[serdefrom=FromType]。这让您可以通过实现From特性来通过中介结构
与Stargateurs类似的一个技巧是在内部类上使用[serdefrom=FromType],这允许您通过实现From特性来通过中间结构
下次别忘了在最后一次MCVE中包括使用说明和所有必需的代码,浪费时间玩Cluedo对于回答一个问题不是很有用:poh my bad,感谢你,下次别忘了在最后一次MCVE中包括使用说明和所有必需的代码,浪费时间玩Cluedo对于回答一个问题不是很有用我的坏朋友,谢谢你,
#[derive(Deserialize)]
struct InnerRepr {
pub data: String,
}
#[derive(Deserialize)]
#[serde(from = "InnerRepr")]
struct Inner {
pub data: Box<Item>,
}
impl From<InnerRepr> for Inner {
fn from(repr: InnerRepr) -> Inner {
Inner{ data: Box::new(parse) }
}
}