rust使用json
JSON 作为使用最广泛的数据结构,学习了解如何在发展最快的 Rust 语言中使用很有必要。
本文中我们将学习到:
- 读取无类型的 JSON。
- 将 JSON 读取为强类型数据结构。
- 写 JSON 字符串。
使用 serde
和 serde-json
Rust 依赖。
无类型 JSON
Rust 是强类型语言,而 JSON 的并没有强制制定自己的数据类型。如果我们不关心 JSON 的数据结构,可以使用serde_json
库将 JSON 当作枚举递归使用。这个结构可以接受 bools, string, numbers, arrays, 和对象(以及 null )。
接下来,我们给我们的新项目(cargo new handle_json
)添加相应依赖:
1 2 | serde_json = "1.0" serde = { version = "1.0" , features = [ "derive" ] } |
serde_json
提供的 from_str()
方法可以处理无类型 JSON 值,JSON 数据会被处理成枚举的形式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | use serde_json::{Value}; fn main() { let json = r#" { "article" : "how to work with json in Rust" , "author" : "tdep" , "paragraph" : [ { "name" : "untyped" }, { "name" : "strongly typed" }, { "name" : "writing json" } ] } "#; let parsed: Value = read_json(json); println!( "\n\n The title of the article is {}" , parsed[ "article" ]) } fn read_json(raw_json:&str) -> Value { let parsed: Value = serde_json::from_str(raw_json).unwrap(); return parsed } |
上面代码的 read_json
函数为解析 JSON 函数,它将字符串处理成 JSON。首先使用serde_json::from_str()
解析字符串,然后解包。如果我们要访问 JSON 中的字段 ,可以使用类似parsed["article"]
这样的代码。
有类型的 JSON
大部分情况下,我们需要使用安全的数据类型在我们的程序中。serde
提供了一个很棒的方法,可以把 JSON 数据映射到 Rust 语言结构。使用方式和上一个例子相似,但是不需要使用 Enum 类型,而是分配一个原生的 Rust 数据结构。
serde
在反序列化时可以检查 JSON 数据类型并匹配,例子如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize)] struct Paragraph { name: String } #[derive(Serialize, Deserialize)] struct Article { article: String, author: String, paragraph: Vec<Paragraph> } fn main() { let json = r#" { "article" : "how to work with json in Rust" , "author" : "tdep" , "paragraph" : [ { "name" : "untyped" }, { "name" : "strongly typed" }, { "name" : "writing json" } ] } "#; let parsed: Article = read_json_typed(json); println!( "\n\n The name of the first paragraph is: {}" , parsed.paragraph[0].name); } fn read_json_typed(raw_json: &str) -> Article { let parsed: Article = serde_json::from_str(raw_json).unwrap(); return parsed } |
和第一个例子有三处不同:第一,是我们定义两个serde
的序列号/反序列化的结构;然后我读取 JSON 数据结构指定 Article
对象作为类型;第三,我们读取解析结构使用的不是 Emun方式,而是 struct
: parsed.paragraph[0].name
。
现在我们可以指定具体的类型和名称读JSON 内容。
但如果我们提供的 JSON 数据和结构不匹配的话:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | { "article" : "how to work with json in Rust" , "author" : "tdep" , "paragraph" : [ { "name" : 1 }, { "name" : "strongly typed" }, { "name" : "writing json" } ] } |
我们把 JSON 中的第一个 name
字段改成数字,程序会出错:
1 | thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error("invalid type: integer `1`, expected a string", line: 8, column: 15)' , src/main.rs:44:58 |
或者我们把“article”
key 改成 “name”
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | { "name" : "how to work with json in Rust" , "author" : "tdep" , "paragraph" : [ { "name" : "untyped" }, { "name" : "strongly typed" }, { "name" : "writing json" } ] } |
程序也会出错:
1 | thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error("missing field `article`", line: 17, column: 1)' , src/main.rs:44:58 |
因为,Rust 无法检测 JSON 中的 article
字段。
这是一种更好的接收 JSON 数据的办法。
接下来让我们看下如何反过来操作:从 Rust 数据结构到 JSON 字符串。
写JSON
我们将使用 serde_json::to_string()
函数将数据结构转换为 JSON 字符串,并使用 serde 的 Serialize
使结构能够被序列化。 让我们看一个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize)] struct Paragraph { name: String } #[derive(Serialize, Deserialize)] struct Article { article: String, author: String, paragraph: Vec<Paragraph> } fn main() { let article: Article = Article { article: String::from( "how to work with json in Rust" ), author: String::from( "tdep" ), paragraph: vec![ Paragraph { name: String::from( "untyped" ) }, Paragraph { name: String::from( "strongly typed" ) }, Paragraph { name: String::from( "writing json" ) } ] }; let json = serde_json::to_string(&article).unwrap(); println!( "the JSON is: {}" , json) } |
我们构建 Article
,然后将其引用传递给 serde_json::to_string()
函数。 运行 cargo 项目的结果:
1 | the JSON is: { "article" : "how to work with json in Rust" , "author" : "tdep" , "paragraph" :[{ "name" : "untyped" },{ "name" : "strongly typed" },{ "name" : "writing json" }]} |
我们已经了解了如何在 Rust 中以快速、安全和高效的方式处理 JSON。 还值得一提的是,我们使用 serde_json::from_string
或 serde_json::to_string
完成的每个操作,也可以使用 serde_json::to_vec
, serde_json::to_writer
不同的是:to_vec
序列化 (或反序列化)到一个vector,以及to_writer
到任何可写的输出(例如一个文件)。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2019-03-19 Dart基础-泛型和库
2019-03-19 Flutter从零到∞学习笔记
2019-03-19 flutter 常用插件
2019-03-19 Dart编程语言入门