Rust解析JSON,结构体序列化和反序列化

JSON一种常用的由键值对组成的数据对象;本文将通过多个例子讲解在Rust中如何解析JSON内容,以及如何将结构体转换成JSON字符串。

在Rust中解析JSON文本通常需要使用一个JSON库。Rust标准库中有一个名为serde的库,它提供了序列化和反序列化结构体和其他数据类型的功能,包括JSON。

添加依赖

要使用serde库解析JSON文本,你需要添加serdeserde_json依赖到你的项目中;

Cargo.toml文件中添加以下行:

[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

解析JSON

对未类型化的JSON进行解析

任何有效的JSON数据都可以转换成serde_json::Value数据结构:

enum Value {
    Null,
    Bool(bool),
    Number(Number),
    String(String),
    Array(Vec<Value>),
    Object(Map<String, Value>),
}

以下函数可用于将JSON数据解析成serde_json::Value结构:

  • serde_json::from_str,用于解析JSON字符串;
  • serde_json::from_slice,用于对字节切片&[u8]进行解析;
  • serde_json::from_reader,从支持io::Read特性的对象中读取数据并解析,比如一个文件或TCP流;

一个使用serde_json::from_str的例子:

fn main() {

    // 一个&str类型的JSON数据
    let data = r#"
        {
            "name": "James Bond",
            "age": 33,
            "pet_phrase": [
                "Bond, James Bond.",
                "Shaken, not stirred."
            ]
        }"#;

    // 转换成serde_json::Value结构
    let v: serde_json::Value = serde_json::from_str(data).unwrap();

    // 通过方括号建立索引来访问部分数据
    println!("NAME: {}\nAGE: {}\n\t{}\n\t{}",
        v["name"],
        v["age"],
        v["pet_phrase"][0],
        v["pet_phrase"][1],
    );
}

程序运行结果

NAME: "James Bond"
AGE: 33
        "Bond, James Bond."
        "Shaken, not stirred."

将JSON解析到数据结构

serde提供了一种将JSON数据自动映射到Rust数据结构的方法;

修改前一个例子:

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct Person {
    name: String,
    age: u8,
    pet_phrase: Vec<String>,
}

fn main() {

    // 一个&str类型的JSON数据
    let data = r#"
        {
            "name": "James Bond",
            "age": 33,
            "pet_phrase": [
                "Bond, James Bond.",
                "Shaken, not stirred."
            ]
        }"#;

    // 转换成 Person 结构
    let p: Person = serde_json::from_str(data).unwrap();

    // 通过方括号建立索引来访问部分数据
    println!("NAME: {}\nAGE: {}\n\t{}\n\t{}",
        p.name,
        p.age,
        p.pet_phrase[0],
        p.pet_phrase[1],
    );
}

该程序运行效果与上一个例子相同,但这一次我们将serde_json::from_str函数的返回值分配给了一个自定义的类型Person

JSON数据与结构体定义不符时将产生错误;

将数据结构转换成JSON字符串

以下是一些可以将数据结构转换成JSON数据的函数:

  • serde_json::to_string,将数据结构转换成JSON字符串;
  • serde_json::to_vec,将数据结构序列化为Vec<u8>
  • serde_json::to_writer,可以序列化到任何实现了io::Write特性的对象中,例如文件或 TCP 流;

使用serde_json::to_string的一个例子:

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct Person {
    name: String,
    age: u8,
    pet_phrase: Vec<String>,
}

fn main() {

    let mut pp = Vec::new();
    pp.push("hello world".to_string());
    pp.push("perfcode.com".to_string());

    let p = Person {
        name: "ho".to_string(),
        age: 18,
        pet_phrase: pp,
    };

    // 序列化为JSON字符串
    let s = serde_json::to_string(&p).unwrap();

    println!("{}",s);
    
}

程序运行效果

{"name":"ho","age":18,"pet_phrase":["hello world","perfcode.com"]}

json!宏

serde提供了一个json!宏来非常自然的构建serde_json::Value对象:

use serde_json::json;

fn main() {

    let info = json!(
        {
            "name": "James Bond",
            "age": 33,
            "pet_phrase":[
                "Bond, James Bond.",
                "Shaken, not stirred."
                ]
        }
    );

    // 通过方括号建立索引来访问部分数据
    println!("NAME: {}\nAGE: {}\n\t{}\n\t{}",
        info["name"],
        info["age"],
        info["pet_phrase"][0],
        info["pet_phrase"][1],
    );

    //序列化
    println!("{}",info.to_string());

}

程序运行效果

NAME: "James Bond"
AGE: 33
        "Bond, James Bond."
        "Shaken, not stirred."
{"age":33,"name":"James Bond","pet_phrase":["Bond, James Bond.","Shaken, not stirred."]}

Value::to_string方法可以将serde_json::Value对象转换成 JSON 字符串;

原创内容,如需转载,请注明出处;

本文地址: https://www.perfcode.com/rust-serde/serde-json.html

分类: 计算机技术
推荐阅读:
Python 列表去重的几种方法 列表去重是指通过消除重复的元素,将列表中的所有唯一元素保留下来的操作;在Python中,存在多种方法删除列表中重复的元素,下面是一些常用的方法;
TypeError: 'str' object does not support item assignment 解决方法 引起 TypeError: 'str' object does not support item assignment 错误是因为尝试以下标的方式修改字符串导致的;在Python中,字符串是不可变类型,不能通过下标的方式直接更改某一字符;
Linux显示使用内存最多的十个进程 在Linux系统下,你可以使用一条命令显示当前系统使用内存最多的十个进程:
打开任务管理的一瞬间CPU飙到很高,这种现象正常吗? Windows系统上的任务管理器(进程名Taskmgr.exe)用于实时显示计算机当前有关于性能、进程、服务等信息;细心的朋友会发现,在打开任务管理器的一瞬间,CPU使用率瞬间飙升,基本上会达到100%,随后也会很快回落,那这种现象正常么?
Python bool()函数 在 Python 中,bool() 是一个内置函数,用于将一个值转换为 bool 类型。bool() 函数返回两个值之一:True 或 False。
如何查看Golang版本 不论是Windows,还是Linux环境,要查看Golang版本,只需要在命令行(CMD)或Shell中输入命令: