Rust:如何使用serde_json? 一个Rust的高效JSON处理库

1. json

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于阅读和编写。在现代编程中,处理JSON数据是非常常见的需求。

Rust 作为一种现代编程语言,拥有强大的类型系统和内存安全性。Serde(SERialize/DEserialize)库是 Rust 中用于数据序列化和反序列化的首选库,而 serde_json 是用于处理JSON数据的Serde的一部分。

2. 设置和配置

首先,需要在 Cargo.toml 中添加 serdeserde_json 作为依赖:

ini 复制代码
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

接着,在Rust 文件中引用它们:

rust 复制代码
extern crate serde;
extern crate serde_json;

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

3. 序列化:Rust数据结构到JSON

序列化是将 Rust 的数据结构转化为 JSON 格式的字符串。下面是一些基础的示例。

基本序列化示例

使用 serde_json::to_string 将 Rust 结构体转换为 JSON 字符串:

rust 复制代码
use serde::{Serialize, Deserialize};
use serde_json::Result;

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

fn main() -> Result<()> {
    let john = Person {
        name: "John".to_string(),
        age: 30,
    };

    let json_str = serde_json::to_string(&john)?;
    println!("{}", json_str);

    Ok(())
}

使用属性定制序列化

你可以使用 Serde 的派生属性来定制序列化行为。例如,改变 JSON 中字段的名称:

rust 复制代码
#[derive(Serialize, Deserialize)]
struct Person {
    #[serde(rename = "fullName")]
    name: String,
    age: u8,
}

4. 反序列化:JSON到Rust数据结构

反序列化是将 JSON 格式的字符串转化为 Rust 的数据结构。下面是一些基础的示例。

基本反序列化示例

使用 serde_json::from_str 将 JSON 字符串转换为 Rust 结构体:

ini 复制代码
let json_str = "{"name":"John","age":30}";
let john: Person = serde_json::from_str(json_str)?;

使用属性定制反序列化

你可以使用相同的派生属性来定制反序列化行为,比如为缺失的字段提供默认值:

rust 复制代码
#[derive(Serialize, Deserialize)]
struct Person {
    name: String,
    #[serde(default = "default_age")]
    age: u8,
}

fn default_age() -> u8 {
    18
}

5. 处理动态JSON:serde_json::Value

有时候,你可能需要处理动态结构的 JSON 数据。

使用 serde_json::Value

serde_json::Value 是一个枚举,用于存储任意的 JSON 数据。

ini 复制代码
use serde_json::Value;

let json_str = "{"name":"John","age":30}";
let v: Value = serde_json::from_str(json_str)?;

使用 json!

你可以使用 json! 宏来更直观地创建 JSON 数据。

rust 复制代码
use serde_json::json;

let john = json!({
    "name": "John",
    "age": 30
});

6. 错误处理

当序列化或反序列化操作失败时,Serde 会返回 serde_json::Error 类型的错误。

rust 复制代码
let res: Result<Person, serde_json::Error> = serde_json::from_str("{"age":30}");

if let Err(e) = res {
    println!("Error: {}", e);
}

7.常用方法

1. from_reader

从 I/O 流中反序列化一个 JSON 对象。

css 复制代码
use serde::Deserialize;
use serde_json::from_reader;
use std::fs::File;

#[derive(Deserialize)]
struct Person {
    name: String,
    age: u8,
}

fn main() {
    let file = File::open("person.json").unwrap();
    let p: Person = from_reader(file).unwrap();
    println!("Name: {}, Age: {}", p.name, p.age);
}

2. from_slice

从字节片段中反序列化一个 JSON 对象。

css 复制代码
use serde::Deserialize;
use serde_json::from_slice;

#[derive(Deserialize)]
struct Person {
    name: String,
    age: u8,
}

fn main() {
    let json_data = r#"{"name": "John", "age": 30}"#;
    let p: Person = from_slice(json_data.as_bytes()).unwrap();
    println!("Name: {}, Age: {}", p.name, p.age);
}

3. from_str

从字符串中反序列化一个 JSON 对象。

css 复制代码
use serde::Deserialize;
use serde_json::from_str;

#[derive(Deserialize)]
struct Person {
    name: String,
    age: u8,
}

fn main() {
    let json_data = r#"{"name": "John", "age": 30}"#;
    let p: Person = from_str(json_data).unwrap();
    println!("Name: {}, Age: {}", p.name, p.age);
}

4. from_value

serde_json::Value 对象中解析一个类型。

css 复制代码
use serde::Deserialize;
use serde_json::{from_value, Value};

#[derive(Deserialize)]
struct Person {
    name: String,
    age: u8,
}

fn main() {
    let value: Value = serde_json::json!({"name": "John", "age": 30});
    let p: Person = from_value(value).unwrap();
    println!("Name: {}, Age: {}", p.name, p.age);
}

5. to_string

序列化一个对象为 JSON 字符串。

rust 复制代码
use serde::Serialize;
use serde_json::to_string;

#[derive(Serialize)]
struct Person {
    name: String,
    age: u8,
}

fn main() {
    let p = Person {
        name: "John".to_string(),
        age: 30,
    };
    let json_data = to_string(&p).unwrap();
    println!("{}", json_data);
}

6. to_string_pretty

序列化一个对象为漂亮(缩进)的 JSON 字符串。

rust 复制代码
use serde::Serialize;
use serde_json::to_string_pretty;

#[derive(Serialize)]
struct Person {
    name: String,
    age: u8,
}

fn main() {
    let p = Person {
        name: "John".to_string(),
        age: 30,
    };
    let json_data = to_string_pretty(&p).unwrap();
    println!("{}", json_data);
}

7. to_value

将一个类型转换为 serde_json::Value

rust 复制代码
use serde::Serialize;
use serde_json::to_value;

#[derive(Serialize)]
struct Person {
    name: String,
    age: u8,
}

fn main() {
    let p = Person {
        name: "John".to_string(),
        age: 30,
    };
    let value = to_value(&p).unwrap();
    println!("{:?}", value);
}

8. to_vec

将一个对象序列化为 JSON 字节向量。

rust 复制代码
use serde::Serialize;
use serde_json::to_vec;

#[derive(Serialize)]
struct Person {
    name: String,
    age: u8,
}

fn main() {
    let p = Person {
        name: "John".to_string(),
        age: 30,
    };
    let json_data = to_vec(&p).unwrap();
    println!("{:?}", json_data);
}

9. to_vec_pretty

将一个对象序列化为漂亮(缩进)的 JSON 字节向量。

rust 复制代码
use serde::Serialize;
use serde_json::to_vec_pretty;

#[derive(Serialize)]
struct Person {
    name: String,
    age: u8,
}

fn main() {
    let p = Person {
        name: "John".to_string(),
        age: 30,
    };
    let json_data = to_vec_pretty(&p).unwrap();
    println!("{:?}", json_data);
}

10. to_writer

将一个对象序列化为 JSON 并写入到 I/O 流。

rust 复制代码
use serde::Serialize;
use serde_json::to_writer;
use std::fs::File;

#[derive(Serialize)]
struct Person {
    name: String,
    age: u8,
}

fn main() {
    let p = Person {
        name: "John".to_string(),
        age: 30,
    };
    let writer = File::create("person.json").unwrap();
    to_writer(writer, &p).unwrap();
}

11. to_writer_pretty

将一个对象序列化为漂亮(缩进)的 JSON 并写入到 I/O 流。

rust 复制代码
use serde::Serialize;
use serde_json::to_writer_pretty;
use std::fs::File;

#[derive(Serialize)]
struct Person {
    name: String,
    age: u8,
}

fn main() {
    let p = Person {
        name: "John".to_string(),
        age: 30,
    };
    let writer = File::create("person_pretty.json").unwrap();
    to_writer_pretty(writer, &p).unwrap();
}

8.资料参考

serde_json

相关推荐
beifengtz10 小时前
【Rust调用Windows API】获取正在运行的全部进程信息
rust·windows api
monkey_meng10 小时前
【Rust中的项目管理】
开发语言·rust·源代码管理
喜欢打篮球的普通人10 小时前
rust高级特征
开发语言·后端·rust
VertexGeek11 小时前
Rust学习(四):作用域、所有权和生命周期:
java·学习·rust
sagima_sdu12 小时前
Py2Neo 库将 Json 文件导入 Neo4J
oracle·json·neo4j
集成显卡13 小时前
axios平替!用浏览器自带的fetch处理AJAX(兼容表单/JSON/文件上传)
前端·ajax·json
Dontla17 小时前
Rust泛型系统类型推导原理(Rust类型推导、泛型类型推导、泛型推导)为什么在某些情况必须手动添加泛型特征约束?(泛型trait约束)
开发语言·算法·rust
梦想画家17 小时前
精通rust宏系列教程-入门篇
rust·元编程·rust宏
喜欢打篮球的普通人17 小时前
rust模式和匹配
java·算法·rust
monkey_meng19 小时前
【Rust类型驱动开发 Type Driven Development】
开发语言·后端·rust