当前位置: 首页 > news >正文

json学习路线

学习 nlohmann/json 这个项目有两种角度:

✅ 你想学哪种?我可以分别给你指引:

学习角度 你想学的是 对应建议
🎯 用户角度(日常使用) 如何使用它来解析/生成 JSON 阅读官方文档 + 写小项目练练
⚙️ 开发者角度(源码剖析) 它是如何实现 JSON 的(模板、结构等) 阅读源码 + 分析 AST + 阅读测试用例

一、🎯 用户角度(快速掌握使用 json 库)

✅ 第一步:先看官方文档示例

官网仓库就有清晰用法:
📖 https://github.com/nlohmann/json#examples

常用操作:

json j; // 创建空对象
j[“name”] = “Hergo”; // 添加键值
j[“skills”] = {“C++”, “Neovim”};
std::string s = j.dump(2); // 转成字符串(2 表示缩进)

✅ 第二步:写几个小练习项目

项目名 功能
💾 配置文件加载器 从 config.json 读取配置
🧙‍♂️ 玩家存档系统 把类序列化为 JSON 保存(to_json/from_json)
📬 网络请求响应解析器 解析 REST API 返回的 JSON 结构
🧰 命令行工具设置 支持 --config config.json 参数

✅ 第三步:掌握进阶用法
• 自定义类型的序列化:

struct Player {
std::string name;
int level;
};

NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Player, name, level)

json j = Player{“Hergo”, 42};

•	用 at() + 异常处理保证安全访问:

try {
std::string name = j.at(“name”);
} catch (json::out_of_range& e) {
std::cerr << “Missing key!” << std::endl;
}

二、⚙️ 开发者角度(深入源码,学现代 C++)

✅ 推荐从这几部分看起:

模块文件名 功能简述
json.hpp 主文件,定义了所有 JSON 逻辑
json_value.hpp 定义 basic_json 的数据结构
json_pointer.hpp 实现 /key1/key2 风格的 JSON 指针
exceptions.hpp 所有异常类定义
lexer.hpp / parser.hpp 手动实现 JSON 解析器(非依赖第三方)

✅ 学习建议
1. 阅读 basic_json 的定义,理解其底层用的是 std::variant(或自定义 union 构造)
2. 学会阅读重载的 operator[] 和 operator=,理解智能行为(自动类型转换)
3. 看 parser / lexer,学习手写解析器(不是使用第三方 json 库解析)
4. 看 unit_tests 文件夹,了解作者测试的逻辑、设计模式(Catch2)

📚 推荐资源
• 官方文档:https://json.nlohmann.me
• 示例项目:https://github.com/nlohmann/json/tree/develop/examples
• 中文教程(第三方):
• https://zhuanlan.zhihu.com/p/266012688
• https://learnku.com/articles/55023
• ChatGPT 🧠:可以随时问我你不懂的源码段落或语法!

🎁 Bonus:我可以提供
• ✅ 一个 VSCode/CMake 项目模板(含 config 读取、序列化存档示例)
• ✅ 一个源码分析路线图(告诉你先看哪几段)
• ✅ 一份学习任务清单(从易到难)

你是希望 从“会用”开始,做几个项目学起来?
还是想深入源码,了解它如何用现代 C++ 模板魔法实现 JSON 功能?

👉 告诉我你更偏向哪个方向,我可以给你量身定制学习计划。

太好了!如果你想深入分析 nlohmann/json 的源码实现,了解它是如何用现代 C++ 写出一个强大又优雅的 JSON 库,下面是一份【推荐阅读顺序 + 每一部分的关注重点】路线图 🔍。

🧭 nlohmann/json 源码分析路线图(2025版)

版本基于 GitHub 最新主分支(3.11+),主文件为 json.hpp,包含整个实现。

🗂 文件结构简述

在安装版中其实只有一个文件:

json.hpp ← 所有内容都在这一个头文件里(2 万多行)

而在源码开发版中,会看到:

include/nlohmann/json.hpp ← 主接口头文件
include/nlohmann/detail/* ← 所有实现细节封装
test/ ← 单元测试
doc/ ← 文档

📌 推荐分析顺序(按功能难度递进)

🔹 第 1 步:快速理解入口类型 basic_json

🔍 文件位置:

// json.hpp
template <typename…>
class basic_json { … };

📌 关注重点:
• 类模板定义和别名 using json = basic_json<…>
• 它的成员变量 m_value 是一个 union 或 variant 类型(存储字符串、对象、数组等)

🔹 第 2 步:了解 JSON 的底层数据结构

🔍 位置:

// detail/value_t.hpp
enum class value_t { null, object, array, string, boolean, number_integer, … };

📌 关注重点:
• 它用枚举 value_t 区分各种 JSON 类型
• 不同类型存在于 union 或 std::variant 里
• m_type + m_value 是 basic_json 的底层结构(C++17 以前用手写 union)

🔹 第 3 步:关注 operator[] 和访问接口

🔍 方法:

// json.hpp
json& operator[](const std::string&);
const json& operator[](const std::string&) const;

📌 学会看:
• 如何判断当前对象是 object,然后返回 map 的 value
• 如果是空值,则自动变成 object/array(“implicit type conversion”)

🔹 第 4 步:解析部分(parser)

🔍 文件:

detail/input/input_adapter.hpp
detail/parser.hpp
detail/lexer.hpp

📌 推荐阅读顺序:
• lexer.hpp:词法分析器,使用 char-by-char 状态机生成 token
• parser.hpp:递归下降解析器,将 token 组装为 JSON 值
• input_adapter.hpp:统一多种输入源(istream, string, file)

🔹 第 5 步:序列化与反序列化

🔍 文件:

detail/output/output_adapter.hpp
detail/serializer.hpp

📌 看点:
• json::dump() 调用的就是 serializer 类
• 输出是如何支持缩进、转义符、空格控制的
• 序列化是否支持 unicode,是否兼容标准 JSON

🔹 第 6 步:to_json / from_json 模板魔法 ✨

🔍 文件:

json.hpp 内部宏:NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE 等

📌 看点:
• 如何通过模板特化 / SFINAE 实现类型自动注册
• 如何通过 adl_serializer 来序列化任意类型

🔹 第 7 步:异常类设计

🔍 文件:

detail/exceptions.hpp

📌 看点:
• json::parse_error, type_error, invalid_iterator 等如何继承标准异常类
• 如何优雅抛出带上下文位置的错误信息

🔹 第 8 步:测试用例(加强理解)

🔍 文件夹:

test/src/
test/data/

📌 看点:
• Catch2 框架写的单元测试
• 所有函数接口都配套测试用例(能快速看到各种极限情况)

🔧 工具辅助建议:

工具/插件 用途
VSCode / CLion 阅读、跳转函数接口
C++ AST Viewer 分析模板展开和类型推导
ccls / clangd 静态分析函数实现关系
Doxygen 本地生成源码文档

✅ 路线图总结(图示)

[1] basic_json 定义

[2] value_t 类型系统

[3] operator[] / at()

[4] lexer + parser(解析器)

[5] serializer(输出)

[6] to_json/from_json 特化技巧

[7] 异常系统

[8] 单元测试辅助验证

💡 进阶学习建议
• 对模板不熟?→ 先学一下 SFINAE, enable_if, CRTP
• 想模仿写一个 mini-json?→ 推荐拆成 tokenizer + parser + dumper 三个类写一遍

如果你想我为这个路线图生成一个带书签的本地 HTML 文档(比如注释清晰的 json.hpp + 阅读提示 + 笔记),我可以为你自动生成 ✅。

需要吗?

// ====== nlohmann/json.hpp 源码学习路线导读版 ======
// 本文件基于 v3.11.x,添加了注释、分区、引导说明,便于 C++ 开发者深入理解
// ✅ 启动阅读路线建议:Ctrl+F 搜索关键标记,如:🔹STEP 1, 🔹STEP 2, … 等

// ====================================================
// 🔹 STEP 1: json 类型别名定义
// ====================================================

namespace nlohmann {
template <typename… Args>
class basic_json {
// 核心数据结构
value_t m_type; // JSON 类型枚举
union json_value m_value; // 储存各种类型
};

using json = basic_json<>;

}

// ====================================================
// 🔹 STEP 2: JSON 类型枚举 & 存储结构
// ====================================================
enum class value_t {
null, object, array, string, boolean, number_integer, number_unsigned, number_float, discarded
};

union json_value {
std::map<std::string, json>* object;
std::vector* array;
std::string* string;
bool boolean;
int64_t number_integer;
double number_float;
// …
};

// ====================================================
// 🔹 STEP 3: 操作符重载:operator[]
// ====================================================
json& operator[](const std::string& key) {
// 如果当前不是 object,自动转为 object
// 返回对应的键值
}

// ====================================================
// 🔹 STEP 4: 解析器:lexer + parser
// ====================================================

// lexer.hpp: 字符流 → token
// parser.hpp: token → json 对象

// 示例:
// json::parse(“{ “name”: “Hergo” }”);

// ====================================================
// 🔹 STEP 5: dump 与序列化
// ====================================================

std::string dump(int indent = -1) const {
// 序列化 json 为字符串
}

// ====================================================
// 🔹 STEP 6: to_json / from_json 自动映射机制
// ====================================================

template
struct adl_serializer {
static void to_json(json& j, const T& value);
static void from_json(const json& j, T& value);
};

// NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE 宏会自动注册这些

// ====================================================
// 🔹 STEP 7: 异常类结构
// ====================================================

class parse_error : public std::exception { /* … / };
class type_error : public std::exception { /
… */ };

// ====================================================
// 🔹 STEP 8: Catch2 单元测试(位于 test/)
// ====================================================
// 建议阅读 test/src/parse.cpp 和 test/src/operator.cpp

// ========== 更多内容请参考官方文档:https://json.nlohmann.me ==========

http://www.lryc.cn/news/580442.html

相关文章:

  • C 中的 uintptr_t 类型
  • 深入解析享元模式:通过共享技术高效支持大量细粒度对象
  • ai 工程图相关论文集合
  • HarmonyOS:创建ArkTS卡片
  • HTML知识复习2
  • 汽车制造车间检测机器人与PLC无线以太网实时控制方案
  • 计算机技术的进阶之路:从基础到前沿的深度探索
  • 【网络】Linux 内核优化实战 - net.ipv4.tcp_timestamps
  • Oracle 高级 SQL 查询与函数详解:多表连接、子查询、聚合、分析函数
  • 3dmax一键烘焙很多张贴图合并成一张贴图插件支持fbx/obj/blender多材质模型合并为一张贴图
  • 光伏发电园区管理系统 - Three.js + Django 实现方案
  • SqueezeBERT:计算机视觉能为自然语言处理在高效神经网络方面带来哪些启示?
  • SQL 转 Java 实体类工具
  • 【内存】Linux 内核优化实战 - net.ipv4.tcp_max_tw_buckets
  • HarmonyOS学习2---Stage模型
  • 接口测试之apifox的使用
  • 在 Ubuntu 下配置 oh-my-posh —— 普通用户 + root 各自使用独立主题(共享可执行)
  • 常见高危端口风险分析与防护指南
  • java中,stream的filter和list的removeIf筛选速度比较
  • 【网络协议安全】任务12:二层物理和单臂路由及三层vlanif配置方法
  • Docker文件操作、数据卷、挂载
  • 猎板 PCB 微孔技术:构建 5G 通信设备高效运行的坚实底座
  • 冒泡和快速排序的区别
  • 【Note】《深入理解Linux内核》 第十八章:深入理解 ext2 与 ext3 文件系统
  • 人工智能-基础篇-18-什么是RAG(检索增强生成:知识库+向量化技术+大语言模型LLM整合的技术框架)
  • 2025使用VM虚拟机安装配置Macos苹果系统下Flutter开发环境保姆级教程--中篇
  • 【算法笔记】4.LeetCode-Hot100-数组专项
  • 多任务学习-ESMM
  • 隐马尔可夫模型(HMM):观测背后的状态解码艺术
  • STM32HAL库总结