0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何使用Serde进行序列化和反序列化

科技绿洲 来源:TinyZ 作者:TinyZ 2023-09-30 17:09 次阅读

Serde 是一个用于序列化和反序列化 Rust 数据结构的库。它支持 JSON、BSON、YAML 等多种格式,并且可以自定义序列化和反序列化方式。Serde 的特点是代码简洁、易于使用、性能高效。它是 Rust 生态中最受欢迎的序列化库之一。

基础用法

安装

在 Rust 项目中使用 Serde,需要在Cargo.toml文件中添加如下依赖:

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

其中features = ["derive"]表示使用 Serde 的派生宏,可以自动生成序列化和反序列化代码。

序列化

使用 Serde 进行序列化,需要先将数据结构实现serde::Serialize trait。例如,我们定义一个Animal结构体,包含名称和年龄两个字段:

#[derive(Serialize)]
struct Animal {
    name: String,
    age: u32,
}

然后,我们可以使用serde_json库将Animal结构体序列化为 JSON 字符串:

use serde_json;

let animal = Animal {
    name: "Tom".to_owned(),
    age: 3,
};
let json = serde_json::to_string(&animal).unwrap();
println!("{}", json); // {"name":"Tom","age":3}

反序列化

使用 Serde 进行反序列化,需要先将数据结构实现serde::Deserialize trait。例如,我们定义一个Animal结构体,包含名称和年龄两个字段:

#[derive(Deserialize)]
struct Animal {
    name: String,
    age: u32,
}

然后,我们可以使用serde_json库将 JSON 字符串反序列化为Animal结构体:

use serde_json;

let json = r#"{"name":"Tom","age":3}"#;
let animal: Animal = serde_json::from_str(json).unwrap();
println!("{:?}", animal); // Animal { name: "Tom", age: 3 }

进阶用法

自定义序列化和反序列化

如果默认的序列化和反序列化方式无法满足需求,可以自定义序列化和反序列化方式。例如,我们定义一个Animal结构体,包含名称和年龄两个字段,但是希望在序列化时,将名称转换为大写字母,反序列化时,将名称转换为小写字母:

use serde::{Serialize, Deserialize, Serializer, Deserializer};

#[derive(Serialize, Deserialize)]
struct Animal {
    #[serde(serialize_with = "serialize_name", deserialize_with = "deserialize_name")]
    name: String,
    age: u32,
}

fn serialize_name< S >(name: &String, serializer: S) - > Result< S::Ok, S::Error >
where
    S: Serializer,
{
    serializer.serialize_str(&name.to_uppercase())
}

fn deserialize_name< 'de, D >(deserializer: D) - > Result< String, D::Error >
where
    D: Deserializer< 'de >,
{
    let name = String::deserialize(deserializer)?;
    Ok(name.to_lowercase())
}

Animal结构体中,我们使用#[serde(serialize_with = "serialize_name", deserialize_with = "deserialize_name")]指定了自定义的序列化和反序列化方法。serialize_name函数将名称转换为大写字母,deserialize_name函数将名称转换为小写字母。

序列化和反序列化枚举

Serde 支持序列化和反序列化枚举类型。例如,我们定义一个Animal枚举,包含狗和猫两种类型:

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
enum Animal {
    Dog { name: String, age: u32 },
    Cat { name: String, age: u32 },
}

在序列化和反序列化枚举类型时,需要使用#[serde(tag = "type")]指定枚举类型的标签,例如:

use serde_json;

let dog = Animal::Dog { name: "Tom".to_owned(), age: 3 };
let json = serde_json::to_string(&dog).unwrap();
println!("{}", json); // {"type":"Dog","name":"Tom","age":3}

let json = r#"{"type":"Dog","name":"Tom","age":3}"#;
let dog: Animal = serde_json::from_str(json).unwrap();
println!("{:?}", dog); // Dog { name: "Tom", age: 3 }

序列化和反序列化结构体中的 Option

Serde 支持序列化和反序列化结构体中的Option类型。例如,我们定义一个Animal结构体,包含名称和年龄两个字段,其中名称可以为空:

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct Animal {
    name: Option< String >,
    age: u32,
}

在序列化和反序列化结构体中的Option类型时,需要使用#[serde(skip_serializing_if = "Option::is_none")]指定当Option值为None时,不进行序列化。例如:

use serde_json;

let animal = Animal { name: Some("Tom".to_owned()), age: 3 };
let json = serde_json::to_string(&animal).unwrap();
println!("{}", json); // {"name":"Tom","age":3}

let animal = Animal { name: None, age: 3 };
let json = serde_json::to_string(&animal).unwrap();
println!("{}", json); // {"age":3}

let json = r#"{"age":3}"#;
let animal: Animal = serde_json::from_str(json).unwrap();
println!("{:?}", animal); // Animal { name: None, age: 3 }

序列化和反序列化结构体中的 Vec

Serde 支持序列化和反序列化结构体中的Vec类型。例如,我们定义一个Zoo结构体,包含多个Animal

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct Zoo {
    animals: Vec< Animal >,
}

在序列化和反序列化结构体中的Vec类型时,Serde 会自动处理序列化和反序列化。例如:

use serde_json;

let zoo = Zoo { animals: vec![
    Animal { name: "Tom".to_owned(), age: 3 },
    Animal { name: "Jerry".to_owned(), age: 2 },
] };
let json = serde_json::to_string(&zoo).unwrap();
println!("{}", json); // {"animals":[{"name":"Tom","age":3},{"name":"Jerry","age":2}]}

let json = r#"{"animals":[{"name":"Tom","age":3},{"name":"Jerry","age":2}]}"#;
let zoo: Zoo = serde_json::from_str(json).unwrap();
println!("{:?}", zoo); // Zoo { animals: [Animal { name: "Tom", age: 3 }, Animal { name: "Jerry", age: 2 }] }

序列化和反序列化结构体中的 HashMap

Serde 支持序列化和反序列化结构体中的HashMap类型。例如,我们定义一个Zoo结构体,包含多个Animal,使用HashMap存储:

use std::collections::HashMap;
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct Zoo {
    animals: HashMap< String, Animal >,
}

在序列化和反序列化结构体中的HashMap类型时,Serde 会自动处理序列化和反序列化。例如:

use serde_json;

let mut animals = HashMap::new();
animals.insert("Tom".to_owned(), Animal { name: "Tom".to_owned(), age: 3 });
animals.insert("Jerry".to_owned(), Animal { name: "Jerry".to_owned(), age: 2 });
let zoo = Zoo { animals };
let json = serde_json::to_string(&zoo).unwrap();
println!("{}", json); // {"animals":{"Jerry":{"name":"Jerry","age":2},"Tom":{"name":"Tom","age":3}}}

let json = r#"{"animals":{"Jerry":{"name":"Jerry","age":2},"Tom":{"name":"Tom","age":3}}}"#;
let zoo: Zoo = serde_json::from_str(json).unwrap();
println!("{:?}", zoo); // Zoo { animals: {"Tom": Animal { name: "Tom", age: 3 }, "Jerry": Animal { name: "Jerry", age: 2 }} }

总结

教程介绍了如何使用 Serde 进行序列化和反序列化,并且介绍了如何自定义序列化和反序列化逻辑。使用 Serde 可以轻松地将 Rust 数据结构转换为任何格式,并且可以通过自定义序列化和反序列化逻辑实现更高级的功能。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 函数
    +关注

    关注

    3

    文章

    3904

    浏览量

    61310
  • 代码
    +关注

    关注

    30

    文章

    4556

    浏览量

    66814
  • 数据结构
    +关注

    关注

    3

    文章

    564

    浏览量

    39905
收藏 人收藏

    评论

    相关推荐

    序列化哈希表到文件

    = BinarySerialize.DeSerialize(strFile);//反序列化文件if (ht != null){ IDictionaryEnumerator dic = ht.GetEnumerator
    发表于 06-18 18:28

    Java序列化的机制和原理

    对象的序列化反序列化也算是Java基础的一部分,下面对Java序列化的机制和原理进行一些介绍。Java序列化算法透析Serializati
    发表于 07-10 07:27

    请问怎么才能在Spartan 6 Deserialier上抖动简单地反序列化6个?

    如果在1700ps周期设计上有700ps数据抖动,可以简单地反序列化6个没有问题吗?以上来自于谷歌翻译以下为原文 If there is 700ps Data jitter on 1700ps
    发表于 07-19 08:56

    LabVIEW序列化编程,可做通用配置架构

    LabVIEW序列化编程,可做通用配置架构[img=110,0][/img][img=110,0][/img]
    发表于 04-23 16:47

    Virtex ISERDES_NODELAY对快速4线总线进行反序列化怎么实现?

    你好朋友。我想使用Virtex ISERDES_NODELAY对快速4线总线进行反序列化。总线大约为700 MHz。我想确保反序列化的信号不是异相的。我的意思是,如果其中一个ISERDES由于内部路由延迟而稍后将复位,则
    发表于 06-01 16:54

    c语言序列化反序列化有何区别

    这里写自定义目录标题c语言序列化反序列化tplut.htplut.c测试代码参考c语言序列化反序列化网络调用,数据传输都需要把数据序列化
    发表于 07-14 07:32

    关于c语言序列化反序列化的知识点看完你就懂了

    关于c语言序列反序列化的知识点你就懂了
    发表于 10-15 08:47

    SpringMVC JSON框架的自定义序列化反序列化

    执行trim方法进行处理。此方案只有逐个添加注解,工作量较大。方案:实现ObjectDeserializer接口ObjectDeserializer接口为可以实现自定义反序列化实现接口,配合
    发表于 10-10 16:02

    linux内核如何为imx8x添加序列化器和反序列化器驱动程序?

    当我阅读 AN13275 文档“How to enable linux BSP L5.4 on a new imx8/8x board”时,有一个关于在下表中添加序列化器、解串器驱动程序的问题这些
    发表于 03-15 06:48

    理解PHP反序列化漏洞

    理解PHP反序列化漏洞
    发表于 09-07 11:03 7次下载
    理解PHP<b class='flag-5'>反序列化</b>漏洞

    java序列化反序列化范例和JDK类库中的序列化API

    一、序列化反序列化的概念 把对象转换为字节序列的过程称为对象的序列化。 把字节序列恢复为对象的过程称为对象的
    发表于 09-27 10:13 6次下载

    static属性为什么不会被序列化

    实现序列化反序列化为什么要实现Serializable接口?
    的头像 发表于 07-15 11:03 1501次阅读

    基于反序列化过采样数据的时钟和数据恢复单元

    电子发烧友网站提供《基于反序列化过采样数据的时钟和数据恢复单元.pdf》资料免费下载
    发表于 09-13 10:41 0次下载
    基于<b class='flag-5'>反序列化</b>过采样数据的时钟和数据恢复单元

    什么是序列化 为什么要序列化

    什么是序列化? “序列化”(Serialization )的意思是将一个对象转化为字节流。 这里说的对象可以理解为“面向对象”里的那个对象,具体的就是存储在内存中的对象数据。 与之相反的过程是“反序列化
    的头像 发表于 09-14 17:22 1545次阅读
    什么是<b class='flag-5'>序列化</b> 为什么要<b class='flag-5'>序列化</b>

    如何用C语言进行json的序列化反序列化

    json是目前最为流行的文本数据传输格式,特别是在网络通信上广泛应用,随着物联网的兴起,在嵌入式设备上,也需要开始使用json进行数据传输,那么,如何快速简洁地用C语言进行json的序列化
    的头像 发表于 10-07 11:05 844次阅读