rust学习(7)-关于序列化与反序列化

1 普通版本

结构体和json字符串里的每个字段一一对应

[dependencies]
serde_derive = "1.0.130"
serde = "1.0.130"
serde_json = "1.0.67"

#[macro_use]
extern crate serde_derive;

extern crate serde;
extern crate serde_json;

#[derive(Serialize, Deserialize, Debug)]
struct Stu {
    name: String,
    id: i32,
    score: i32
}

fn main() {
    let stu1 = Stu { name: "张三".to_string(), id: 007, score: 100 };
    let serialized = serde_json::to_string(&stu1).unwrap();//序列化,结构体变量转json字符串
    println!("serialized = {}", serialized);
    let stu2: Stu = serde_json::from_str(&serialized).unwrap();//反序列化,json字符串转结构体变量,需要指定结构体变量stu2的类型为Stu,而且要求Stu这个结构体变量的字段和Json字符串的字段一一对应
    println!("deserialized = {:#?}", stu2);
}

2 特殊类型

结构体和json字符串里的每个字段并非一一对应,结构体里有些字段,在json字符串中没有,这时候就要把没有出现的字段类型改为Option。

//mytest/Cargo.toml
[package]
name = "mytest"
version = "0.1.0"
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
serde_derive = "1.0.130"
serde = "1.0.130"
serde_json = "1.0.67"

//mytest/src/lib.rs
#[macro_use]
extern crate serde_derive;

use std::fmt::Debug;
#[derive(Serialize, Deserialize, Debug)]
pub struct Address {
    province: String,
    city: String,
    house_number: Option<String>,
}

#[derive(Serialize, Deserialize, Debug)]
 pub struct BirthDate (pub u8,pub u8,pub u8);

 #[derive(Serialize, Deserialize, Debug)] 
pub struct UserInfo{
    username: String,
    password : String,
    pub birth_date: Option<BirthDate>,
    school: String,
    address : Option<Address>,

}

//mytest/src/main.rs

use mytest::UserInfo;
use mytest::BirthDate;
use  serde;
use  serde_json;



fn main() { 
     let json =r#"{
            "username": "hhh",
            "password": "123456",
            "school": "csust",
            "address": {
                "province": "hn",
                "city": "cs",
                "house_number": "9527"
            }
     }"#;
     let mut user_info: UserInfo = serde_json::from_str(&json).unwrap(); //反序列化
     println!("{:#?}",user_info); //使用{} 这个format的话,要derive Display trait ,Display这个trait里没有默认实现,所以需要自己取实现
                                    //使用 {:?} or {:#?} (后者是有换行功能) 这两个format的话,要derive Debug trait,Debug trait有默认实现
     
    user_info.birth_date = Some(BirthDate(3,6,8));
    println!("{:#?}",user_info);

    let json = serde_json::to_string(&user_info).unwrap();  //序列化
    println!("{:#?}",user_info);

}

//output
/* 
UserInfo {
    username: "hhh",
    password: "123456",
    birth_date: None,
    school: "csust",
    address: Some(
        Address {
            province: "hn",
            city: "cs",
            house_number: Some(
                "9527",
            ),
        },
    ),
}
UserInfo {
    username: "hhh",
    password: "123456",
    birth_date: Some(
        BirthDate(
            3,
            6,
            8,
        ),
    ),
    school: "csust",
    address: Some(
        Address {
            province: "hn",
            city: "cs",
            house_number: Some(
                "9527",
            ),
        },
    ),
}
UserInfo {
    username: "hhh",
    password: "123456",
    birth_date: Some(
        BirthDate(
            3,
            6,
            8,
        ),
    ),
    school: "csust",
    address: Some(
        Address {
            province: "hn",
            city: "cs",
            house_number: Some(
                "9527",
            ),
        },
    ),
}
*/



*/


3 json转Value类型

value类型是万能类型,什么类型的值都能装,在处理把json字符串反序列化的时候很个很好用的容器。


[dependencies]  //使用了第三方包,必须加包的依赖
serde_json = "1.0.67"

//src/main.rs
//use serde_json::json; 把使用的条目导入作用域相当于,把这个json宏和Vaule结构的定义在这里展开,那么相当于main函数和json宏的定义处于同一个模块内,同以级别,main里可以直接这样使用let v: Value = json!({"username": "123"});
//use serde_json::Value;  不把使用的条目导入作用域也可以,不过使用的时候就要从crate根(可以写crate字面值(当这个crate是lib.rs对应的crate时可以这样),和crate名)开始写 
    let s: String = "fuck".to_string();
    let v: serde_json::Value = serde_json::json!({
        "name" : s,
        "sex" : s
    });
    println!("{}",s);
    println!("{:#?}",v);
    
}

4 Value 转结构体

let response: OperationResponse = serde_json::from_value(response)?;

5 取Serde_json::Value 中的值,不用模式匹配一层一层打开

use serde_json::{Result, Value};

fn untyped_example() -> Result<()> {
    // Some JSON input data as a &str. Maybe this comes from the user.
    let data = r#"
        {
            "name": "John Doe",
            "age": 43,
            "phones": [
                "+44 1234567",
                "+44 2345678"
            ]
        }"#;

    // Parse the string of data into serde_json::Value.
    let v: Value = serde_json::from_str(data)?;
    // let v = serde_json::from_str::<Value>(data)?; // 或者可以这样写

    // Access parts of the data by indexing with square brackets.
    //对于Value::Object(Map<String,Value>和Value::Array(Vec<Value>),取里面的值可以用索引一次取两层,没必要用if let 匹配取
    println!(" {:#?} \n \n {:#?}", v["name"], v["phones"][0]);
    Ok(())
}

//output 
 String(
    "John Doe",
) 
 
 String(
    "+44 1234567",
)

6 #[serde(rename(deserialize = “XXX”, serialize = “XXX”))]的使用

extern crate serde;
extern crate serde_json;
#[derive(Serialize, Deserialize, Debug)]  //to do实现display  做笔记
struct Stu {
    #[serde(rename(deserialize = "deserialize_name", serialize = "serialize_name"))]
    name: String,
    #[serde(rename(deserialize = "deserialize_id", serialize = "serialize_id"))]
    id: i32,
    #[serde(rename(deserialize = "deserialize_score", serialize = "serialize_score"))]
    score: i32,
    #[serde(rename(deserialize = "country", deserialize = "province", deserialize = "city", deserialize = "block"))]
    home: String,
}
#[test]
fn test3() {
    let stu = Stu {
        name: "tony".to_string(),
        id: 9527,
        score: 100,
        home: "Hunan".to_string(),
    };
    let serialize = serde_json::to_string(&stu).unwrap();
    println!("{}",serialize);

    let deserialize = serde_json::from_str::<Stu>("{\"serialize_name\":\"tony\",\"serialize_id\":9527,\"serialize_score\":100}");  //少了rust 结构体的 home 字段
    if deserialize.is_err()
    {
        println!("反序列失败");
    } else {
        println!("{:#?}",deserialize.unwrap());
    }

    let deserialize = serde_json::from_str::<Stu>("{\"deserialize_name\":\"tony\",\"deserialize_id\":9527,\"deserialize_score\":100,\"country\":\"CN\"}");
    if deserialize.is_err()
    {
        println!("反序列失败");
    } else {
        println!("{:#?}",deserialize.unwrap());
    }

    let deserialize = serde_json::from_str::<Stu>(r#"{"deserialize_name":"tony","deserialize_id":9527,"deserialize_score":100,"block":"CS"}"#);
    if deserialize.is_err()
    {
        println!("反序列失败");
    } else {
        println!("{:#?}",deserialize.unwrap());
    }
}
/* 
output

{"serialize_name":"tony","serialize_id":9527,"serialize_score":100,"home":"Hunan"}
反序列失败
Stu {
    name: "tony",
    id: 9527,
    score: 100,
    home: "CN",
}
Stu {
    name: "tony",
    id: 9527,
    score: 100,
    home: "CS",
}
*/

7 浅谈json string

json string 有两种写法

  1. "{\"deserialize_name\":\"tony\",\"deserialize_id\":9527,\"deserialize_score\":100,\"country\":\"CN\"}"这种写法使用了转义字符\""的意思由字符串结束转成了双引号字符(成为字符串的许多字符里的一份子)
  2. r#"{"deserialize_name":"tony","deserialize_id":9527,"deserialize_score":100,"block":"CS"}"#这种是用了r#""#把字符串包起来,这种写法较为简单

猜你喜欢

转载自blog.csdn.net/qq_40642465/article/details/120386754
今日推荐