首页 > 解决方案 > 如何使用标签从严格的 serde_json 反序列化访问字段

问题描述

我进入了预期Some(Address{...})的地址字段。data我可以从调试打印输出中看到它。

&data.Address = &data.Address.unwrap();

给我静态错误说:“类型配置文件中没有字段Address

let mut data:Profile = serde_json::from_str(json_string).unwrap();
&data.Address = &data.Address.unwrap();

#[derive(Deserialize, Debug, Serialize)]
#[serde(tag = "m_tag")]
pub enum Profile {
   Data{
    #[serde(rename="FirstName")] // to comply with Rust coding standards
    first_name:String,
    LastName: String,
    Age: u32,
    Address:  Option<Address>,
    PhoneNumbers: Vec<String>
   },
   Data2{
    #[serde(rename="FirstName")] // to comply with Rust coding standards
    first_name:String,
    LastName: String,
    Age: u32,
   },

}

#[derive(Serialize, Deserialize)]
struct Address {
    Street: String,
    City: String,
    Country: String
}

更新:Q1)我可以解开值但我想更新 &data.Address 到它。但是我又回到了原始问题,其中 &data 是一种Profile类型并且没有该Address字段。

 match &data {
        Profile::Data {
            first_name,
            LastName,
            Age,
            Address,
            PhoneNumbers,
        } => data.Address =  &Address.as_ref().unwrap(),
        Profile::Data2 {
           first_name,
           LastName,
           Age,
        } => println!("ok"),
    }

标签: rust

解决方案


编辑:

如果字段重叠,则无需创建 Enum。最好将不保证存在的字段声明为可选:

#[derive(Deserialize, Debug, Serialize)]
struct Profile {
  #[serde(rename="FirstName")]
  first_name:String,
  LastName: String,
  Age: u32,
  Address:  Option<Address>,
  PhoneNumbers: Option<Vec<String>>
};

所以现在可以保证该类型Profile有一个Address字段:

let data:Profile = serde_json::from_str(json_string).unwrap();

println!("{:?}", data.Address);

这是一个在Rust Playground中工作的代码示例。


推荐阅读