Rust 使用Box实现结构的反序列化

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实现反序列化,并且

包含框作为成员变量的结构:

类型项目=dyn Fn->结果; 结构内部{ 发布数据:框, } //函数,如类型:Item fn解析->结果{ println!调用parse; 好啊 } 现在出现了一个问题,即自定义为结构内部实现反序列化以反序列化:

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