鸿蒙PC适配llvm-gcc-compat编译安装第三方库serde_json,打造Rust 第三方负责 JSON 字符串与 Rust 类型互转
欢迎加入开源鸿蒙PC社区: https://harmonypc.csdn.net/
欢迎在PC社区平台申请新建项目:https://atomgit.com/OpenHarmonyPCDeveloper
AtomGit 仓库地址:https://atomgit.com/OpenHarmonyPCDeveloper/ohos_rust_cargo
本文讲解鸿蒙 PC 端 Rust 开发环境搭建,鸿蒙基于 musl 库、强制二进制签名,无法直接使用通用 Linux 编译产物。需借助鸿蒙专属包管理器 Harmonybrew,提供两套编译方案:方案一安装 llvm-gcc-compat,零配置开箱即用;方案二仅安装 ohos-sdk,需手动配置 Cargo 链接器,二者都依托 ohos-sdk 完成自动签名编译。
可以来参考一下这个文章搭建环境OpenHarmony 鸿蒙 PC + CodeArts IDE 实现 Rust开发完整开发环境搭建指南
一、两个库分别是什么、作用
1. serde
Rust 行业标准通用序列化/反序列化框架,支持 JSON、YAML、Toml、Bincode 等几乎所有格式。
- 核心功能:把 Rust 结构体、枚举、基础类型转成字节/字符串(序列化);把字符串/字节还原成 Rust 变量(反序列化)
serde/derive特性:提供#[derive(Serialize, Deserialize)]派生宏,自动为结构体生成序列化代码,不用手写转换逻辑- 支持自定义字段名、忽略字段、默认值、嵌套结构体、数组、枚举、泛型
- 无运行时反射,编译期生成代码,性能极高
2. serde_json
serde 的 JSON 专用实现,负责 JSON 字符串与 Rust 类型互转:
- 序列化:Rust struct → JSON 字符串(紧凑/带格式化两种输出)
- 反序列化:JSON 字符串 → Rust struct / Value 动态对象
- 动态操作无固定结构 JSON:
serde_json::Value(Object/Array/Number/String/Bool/Null)
适用开发场景
- Web 后端(Axum/Rocket)HTTP 请求体、返回 JSON 响应
- 读取/写入 JSON 配置文件
- 接口调用:发送 JSON 请求、解析第三方接口返回 JSON
- 缓存、消息队列 JSON 数据编解码
- 动态处理未知结构 JSON(日志、第三方数据)
二、安装依赖
# serde 开启 derive 派生宏特性,同时安装 serde_json
cargo add serde --features derive
cargo add serde_json
自动写入 Cargo.toml
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

三、完整无报错 main.rs
覆盖:固定结构体序列化/反序列化、格式化输出、自定义JSON字段名、忽略字段、动态Value操作、嵌套结构体、数组列表。
use serde::{Deserialize, Serialize};
use serde_json::{json, to_string_pretty, from_str, Value};
// 1. 基础用户结构体,派生序列化、反序列化
#[derive(Debug, Serialize, Deserialize)]
struct User {
// json 内字段名改为 user_name,而非默认 username
#[serde(rename = "user_name")]
username: String,
age: u8,
// 序列化时忽略此字段,反序列化不存在则用默认值
#[serde(skip_serializing, default)]
password: String,
is_vip: bool,
}
// 2. 嵌套结构体演示
#[derive(Debug, Serialize, Deserialize)]
struct Order {
order_id: String,
price: f64,
buyer: User,
goods_list: Vec<String>,
}
fn main() {
// ===================== 一、结构体序列化为 JSON 字符串 =====================
println!("===== 1. 结构体序列化 JSON =====");
let user = User {
username: "zhangsan2026".to_string(),
age: 24,
password: "123456".to_string(),
is_vip: true,
};
// 格式化带换行缩进的JSON
let user_json = to_string_pretty(&user).unwrap();
println!("用户JSON:\n{}", user_json);
// 嵌套结构体
let order = Order {
order_id: "ORD0618001".to_string(),
price: 199.99,
buyer: user,
goods_list: vec!["机械键盘".to_string(), "无线鼠标".to_string()],
};
let order_json = to_string_pretty(&order).unwrap();
println!("\n订单嵌套JSON:\n{}", order_json);
// ===================== 二、JSON字符串反序列化为结构体 =====================
println!("===== 2. JSON 反序列化结构体 =====");
let json_text = r#"{
"user_name": "lisi",
"age": 20,
"is_vip": false
}"#;
let parse_user: User = from_str(json_text).unwrap();
println!("解析后的用户: {:?}", parse_user);
// password 被忽略,使用默认空字符串
println!("密码字段: {}", parse_user.password);
// ===================== 三、动态构造JSON(无固定结构体,json!宏) =====================
println!("\n===== 3. json! 宏快速构造动态JSON =====");
let dynamic_json = json!({
"code": 200,
"msg": "success",
"data": {
"list": [10, 20, 30],
"total": 100
}
});
// Value 转格式化字符串
let dyn_str = to_string_pretty(&dynamic_json).unwrap();
println!("动态构造JSON:\n{}", dyn_str);
// 读取动态JSON内部字段
let code = dynamic_json["code"].as_u64().unwrap();
let total = dynamic_json["data"]["total"].as_u64().unwrap();
println!("响应code: {}, 数据总数: {}", code, total);
// ===================== 四、动态Value 类型操作未知JSON =====================
println!("\n===== 4. Value 动态修改JSON字段 =====");
let mut val: Value = json!({ "count": 1 });
// 修改数字字段
val["count"] = json!(100);
// 新增数组
val["tags"] = json!(["rust", "serde", "json"]);
println!("修改后Value:\n{}", to_string_pretty(&val).unwrap());
}

四、运行命令
cargo run
serde 是 Rust 生态标准序列化/反序列化框架,serde_json 是针对 JSON 的实现,用来实现 结构体 ↔ JSON 字符串 互转、动态JSON对象操作,后端接口、配置文件、网络报文必备。
前置 Cargo.toml 依赖
[dependencies]
# 序列化核心,derive 开启派生宏 Serialize/Deserialize
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
导入包说明
use serde::{Deserialize, Serialize};
use serde_json::{json, to_string_pretty, from_str, Value};
Serialize:特征,结构体转JSONDeserialize:特征,JSON转回结构体json!:宏,快速构建无固定结构的动态JSON对象to_string_pretty:格式化带缩进换行的JSON字符串(打印调试用)
配套还有to_string()压缩无空格JSON(网络传输用)from_str:JSON字符串 → 结构体 / ValueValue:动态JSON枚举类型,代表任意JSON(对象/数组/数字/字符串/null)
一、结构体定义 + serde 属性注解
1. User 基础结构体
#[derive(Debug, Serialize, Deserialize)]
struct User {
#[serde(rename = "user_name")]
username: String,
age: u8,
#[serde(skip_serializing, default)]
password: String,
is_vip: bool,
}
1)派生宏 Serialize, Deserialize
自动为结构体实现序列化、反序列化逻辑,省去手写转换代码。
2)#[serde(rename = "user_name")] 字段重命名
Rust 字段名是 username,但 JSON 里键名要叫 user_name。
- 序列化:
username→ json 键user_name - 反序列化:json 里
user_name自动映射到username
3)#[serde(skip_serializing, default)] 复合注解
两个配置同时生效:
skip_serializing:序列化时忽略此字段
把 User 转 JSON 时,不会输出 password 字段(保护密码不返回前端)default:反序列化时,如果JSON不存在该字段,使用类型默认值
String 默认空字符串,所以示例里没传password,解析后password = ""
2. Order 嵌套结构体
#[derive(Debug, Serialize, Deserialize)]
struct Order {
order_id: String,
price: f64,
buyer: User,
goods_list: Vec<String>,
}
serde 天然支持嵌套结构体、Vec数组,无需额外配置:
buyer: User:JSON中是嵌套对象goods_list: Vec<String>:JSON中是字符串数组
二、模块1:结构体序列化为 JSON 字符串
1. User 序列化
let user = User {
username: "zhangsan2026".to_string(),
age: 24,
password: "123456".to_string(),
is_vip: true,
};
let user_json = to_string_pretty(&user).unwrap();
println!("用户JSON:\n{}", user_json);
执行逻辑
to_string_pretty(&T):接收实现 Serialize 的结构体引用,输出带缩进美化JSON。
根据注解规则:
- 字段
username→ json 键user_name password被skip_serializing忽略,输出的JSON没有password字段
输出JSON片段:
{
"user_name": "zhangsan2026",
"age": 24,
"is_vip": true
}
2. 嵌套 Order 序列化
let order = Order {
order_id: "ORD0618001".to_string(),
price: 199.99,
buyer: user,
goods_list: vec!["机械键盘".to_string(), "无线鼠标".to_string()],
};
let order_json = to_string_pretty(&order).unwrap();
JSON会生成嵌套对象,buyer 内部结构完全复用 User 的序列化规则,数组正常渲染。
三、模块2:JSON字符串反序列化为结构体
let json_text = r#"{
"user_name": "lisi",
"age": 20,
"is_vip": false
}"#;
let parse_user: User = from_str(json_text).unwrap();
println!("解析后的用户: {:?}", parse_user);
println!("密码字段: {}", parse_user.password);
核心逻辑
from_str::<T>(json字符串):将文本JSON转换成目标结构体 T,返回 Result<T, Error>,unwrap() 简化错误处理。
对应注解规则生效
- JSON键
user_name匹配结构体username - JSON 里没有 password 字段,
#[serde(default)]生效,自动填充空字符串""
关键注意
如果去掉 default,JSON缺少password字段时会直接解析报错;加了default则兼容缺省字段。
四、模块3:json! 宏 快速构造动态JSON(无固定结构体)
适用场景
接口返回统一格式(code/msg/data)、临时拼接JSON、结构不固定无法提前定义struct。
let dynamic_json = json!({
"code": 200,
"msg": "success",
"data": {
"list": [10, 20, 30],
"total": 100
}
});
json!{} 宏直接写类JS对象语法,返回 serde_json::Value 类型。
读取内部字段
let code = dynamic_json["code"].as_u64().unwrap();
let total = dynamic_json["data"]["total"].as_u64().unwrap();
Value 像数组/Map一样用 [] 访问嵌套key;as_u64() / as_str() / as_bool() 安全提取对应类型,不存在或类型不匹配返回None。
转字符串
to_string_pretty(&dynamic_json) 把 Value 转为打印用格式化字符串。
五、模块4:Value 动态修改、新增JSON字段
Value 是可变动态JSON容器,适合解析未知结构报文、运行时增删改字段。
let mut val: Value = json!({ "count": 1 });
val["count"] = json!(100);
val["tags"] = json!(["rust", "serde", "json"]);
操作说明
- 必须声明
mut可变 - 赋值右侧必须也是
Value类型,用json!()包装数字、数组、对象 - 直接
val["新key"]赋值即可新增字段,覆盖原有key实现修改
打印输出:
{
"count": 100,
"tags": [
"rust",
"serde",
"json"
]
}
六、核心工具函数区分
| 函数 | 作用 | 使用场景 |
|---|---|---|
to_string(&T) |
压缩无空格JSON | HTTP接口传输,节省流量 |
to_string_pretty(&T) |
带换行缩进美化JSON | 日志打印、调试查看 |
from_str::<T>(text) |
JSON字符串 → 结构体 | 已知报文结构,强类型解析 |
json!{} |
构建Value动态对象 | 结构不固定、临时组装返回体 |
七、常用 serde 注解拓展(补充示例里用到的)
#[serde(rename = "xxx")]字段名映射#[serde(skip_serializing)]序列化忽略#[serde(skip_deserializing)]反序列化忽略#[serde(default)]缺失字段填充类型默认值#[serde(rename_all = "snake_case")]批量自动下划线命名(结构体上)
八、两种开发模式选择
- 强类型结构体模式(示例前两部分)
接口入参、数据库实体、固定报文;编译期校验字段,类型安全,推荐业务主流程使用。 - Value动态模式(后两部分)
第三方未知JSON、动态配置、统一返回包装体;无编译校验,运行时可能类型错误,适合临时、弱结构数据。
九、完整程序输出预览
===== 1. 结构体序列化 JSON =====
用户JSON:
{
"user_name": "zhangsan2026",
"age": 24,
"is_vip": true
}
订单嵌套JSON:
{
"order_id": "ORD0618001",
"price": 199.99,
"buyer": {
"user_name": "zhangsan2026",
"age": 24,
"is_vip": true
},
"goods_list": [
"机械键盘",
"无线鼠标"
]
}
===== 2. JSON 反序列化结构体 =====
解析后的用户: User { username: "lisi", age: 20, password: "", is_vip: false }
密码字段:
===== 3. json! 宏快速构造动态JSON =====
动态构造JSON:
{
"code": 200,
"msg": "success",
"data": {
"list": [
10,
20,
30
],
"total": 100
}
}
响应code: 200, 数据总数: 100
===== 4. Value 动态修改JSON字段 =====
修改后Value:
{
"count": 100,
"tags": [
"rust",
"serde",
"json"
]
}
五、核心API与标签详细说明
1. 两大派生宏
#[derive(Serialize)]:Rust类型 → JSON字符串#[derive(Deserialize)]:JSON字符串 → Rust类型
2. serde 常用字段标签
#[serde(rename = "xxx")]
自定义JSON内字段名称,解决下划线/驼峰命名差异#[serde(skip_serializing)]
序列化时跳过该字段(密码、敏感数据不输出)#[serde(default)]
JSON缺失此字段时,使用类型默认值(空字符串、0、false)#[serde(skip)]
序列化+反序列化都忽略此字段#[serde(rename_all = "camelCase")]
加在结构体上,批量把所有字段转为驼峰命名
3. serde_json 核心函数
serde_json::to_string(&T)
紧凑无换行JSON字符串serde_json::to_string_pretty(&T)
带缩进、换行,人类可读格式化JSONserde_json::from_str::<T>(&str)
JSON文本解析为指定Rust结构体json!({...})宏
快速创建动态serde_json::Value对象,无需定义结构体serde_json::Value动态类型六种分支Value::Object对象mapValue::Array数组Value::Number数字Value::String字符串Value::Bool布尔Value::Null空值
六、典型业务拓展示例
示例1:Web统一返回格式(接口标准响应体)
#[derive(Serialize, Deserialize, Debug)]
pub struct ApiResp<T> {
pub code: i32,
pub msg: String,
pub data: Option<T>,
}
// 成功返回泛型数据
fn success<T: Serialize>(data: T) -> ApiResp<T> {
ApiResp {
code: 200,
msg: "ok".to_string(),
data: Some(data),
}
}
示例2:读取本地JSON配置文件
use std::fs::read_to_string;
fn load_config() -> User {
let text = read_to_string("./config.json").unwrap();
from_str(&text).unwrap()
}
七、优势说明
- 编译期生成序列化代码,无运行时反射,速度远超其他动态序列化库
- 标签系统灵活控制字段映射、过滤、默认值,适配前后端命名差异
serde_json::Value兼容未知结构第三方JSON,不用提前定义结构体- 生态全覆盖:Axum、Tokio、sqlx、chrono、tracing 全部原生支持serde
- 支持泛型、嵌套、数组、枚举、日期等复杂业务类型无缝转换
更多推荐



所有评论(0)