357 lines
8.5 KiB
Markdown
357 lines
8.5 KiB
Markdown
**JSON**(全称 **J**ava**S**cript **O**bject **N**otation)是一种轻量级的**数据交换格式**。
|
||
|
||
简单来说,JSON 就是一种**文本格式**,用来在不同的程序、不同的编程语言、或者客户端与服务器之间传递数据。虽然它的名字里带有 "JavaScript",但它其实是**独立于语言**的。几乎所有的现代编程语言(C++, Python, Java, Go 等)都支持解析和生成 JSON。
|
||
|
||
---
|
||
|
||
### 1. JSON 的核心结构
|
||
|
||
JSON 的结构非常简单,只有两种基本结构:
|
||
|
||
1. **对象 (Object)**:无序的键值对集合(类似于 C++ 的 `std::map` 或 Python 的 `dict`)。
|
||
2. **数组 (Array)**:有序的值的列表(类似于 C++ 的 `std::vector` 或 Python 的 `list`)。
|
||
|
||
### 2. JSON 的语法规则(非常严格!)
|
||
|
||
很多初学者容易把 JavaScript 对象字面量和 JSON 搞混,JSON 的语法要严格得多:
|
||
|
||
1. **数据在键值对中**:`"key": value`
|
||
2. **数据由逗号分隔**:最后一个元素后面**不能**有逗号(虽然部分解析器允许,但标准不允许)。
|
||
3. **花括号保存对象**:`{ ... }`
|
||
4. **方括号保存数组**:`[ ... ]`
|
||
5. **字符串必须用双引号**:这是最容易出错的地方。**必须是 `"`,不能是单引号 `'`**。Key(键)也必须用双引号包围。
|
||
|
||
---
|
||
|
||
### 3. JSON 支持的数据类型
|
||
|
||
JSON 的值(Value)只能是以下 6 种数据类型:
|
||
|
||
| 类型 | 描述 | 示例 |
|
||
| :--- | :--- | :--- |
|
||
| **String** | 字符串 | `"Hello World"` (必须双引号) |
|
||
| **Number** | 数字 | `100`, `-5.5`, `3.14` (不分整型浮点) |
|
||
| **Boolean** | 布尔值 | `true`, `false` (全小写) |
|
||
| **Null** | 空值 | `null` (表示空) |
|
||
| **Object** | 对象 | `{"id": 1}` (嵌套结构) |
|
||
| **Array** | 数组 | `[1, 2, 3]` |
|
||
|
||
*注意:JSON 不支持函数、日期(通常转为字符串)、undefined 或注释。*
|
||
|
||
---
|
||
|
||
### 4. 一个完整的 JSON 示例
|
||
|
||
假设我们要描述一个“程序员”的信息,JSON 文件可能长这样:
|
||
|
||
```json
|
||
{
|
||
"name": "张三",
|
||
"age": 28,
|
||
"isEmployee": true,
|
||
"skills": ["C++", "Python", "Linux"],
|
||
"address": {
|
||
"city": "上海",
|
||
"street": "南京东路",
|
||
"zipcode": null
|
||
},
|
||
"projects": [
|
||
{
|
||
"name": "后台管理系统",
|
||
"status": "completed"
|
||
},
|
||
{
|
||
"name": "AI 助手",
|
||
"status": "developing"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
**解析上面的内容:**
|
||
* 最外层是一个 **Object** `{}`。
|
||
* `"name"` 是键,值是字符串 `"张三"`。
|
||
* `"age"` 是键,值是数字 `28`。
|
||
* `"skills"` 是键,值是一个 **Array** `[]`,里面包含三个字符串。
|
||
* `"address"` 是键,值是一个嵌套的 **Object** `{}`。
|
||
* `"zipcode"` 的值是 `null`。
|
||
|
||
---
|
||
|
||
### 5. 常见应用场景
|
||
|
||
1. **前后端通信**:
|
||
* 前端(网页/App)向服务器请求用户数据,服务器查询数据库后,将数据组装成 JSON 格式返回给前端。
|
||
2. **配置文件**:
|
||
* 很多软件使用 `.json` 文件来存储配置(如 VS Code 的 `settings.json`)。
|
||
3. **数据存储**:
|
||
* NoSQL 数据库(如 MongoDB)直接以类似 JSON 的格式(BSON)存储数据。
|
||
|
||
### 6. JSON 与 C++ (结合你上一个问题)
|
||
|
||
在 C++ 中,标准库没有内置 JSON 解析器,通常使用第三方库(最著名的是 `nlohmann/json`)。
|
||
|
||
JSON 和 `std::variant` 的关系非常紧密。因为 JSON 的值可能是数字、字符串、布尔值等多种类型中的一种,**解析 JSON 的底层实现往往就是基于 `std::variant` 或者类似的联合体机制。**
|
||
|
||
例如,一个简易的 JSON Value 类在 C++ 中可能这样定义:
|
||
|
||
```cpp
|
||
#include <variant>
|
||
#include <string>
|
||
#include <vector>
|
||
#include <map>
|
||
|
||
struct JsonValue; // 前向声明
|
||
|
||
// 定义 JSON 支持的类型
|
||
using JsonVariant = std::variant<
|
||
std::nullptr_t,
|
||
bool,
|
||
double,
|
||
std::string,
|
||
std::vector<JsonValue>, // 数组
|
||
std::map<std::string, JsonValue> // 对象
|
||
>;
|
||
|
||
struct JsonValue {
|
||
JsonVariant value;
|
||
};
|
||
```
|
||
|
||
### 总结
|
||
|
||
* **JSON** 是互联网上最通用的数据快递包装。
|
||
* **语法**:大括号包对象,方括号包数组,Key 必须双引号。
|
||
* **优点**:人眼看得懂,机器好解析,体积小。
|
||
*
|
||
|
||
|
||
为了让你全面理解 JSON,我把例子分成了**基础语法**、**常见结构**和**真实场景**三个类别。
|
||
|
||
### 第一类:基础语法演示
|
||
这些例子展示了 JSON 支持的最基本数据类型。
|
||
|
||
#### 1. 最简单的键值对 (Flat Object)
|
||
这是最基础的形式,类似于一个简单的字典。
|
||
```json
|
||
{
|
||
"username": "admin",
|
||
"timeout": 5000,
|
||
"isEnabled": true,
|
||
"description": null
|
||
}
|
||
```
|
||
|
||
#### 2. 纯数组 (Array)
|
||
JSON 也可以仅仅是一个数组,不包含最外层的键。
|
||
```json
|
||
[
|
||
"Monday",
|
||
"Tuesday",
|
||
"Wednesday",
|
||
"Thursday",
|
||
"Friday"
|
||
]
|
||
```
|
||
|
||
#### 3. 各种数字格式
|
||
JSON 不区分整数和浮点数,统一为 Number。
|
||
```json
|
||
{
|
||
"integer": 42,
|
||
"float": 3.14159,
|
||
"negative": -10,
|
||
"exponent": 2.5e-3
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 第二类:结构化与嵌套
|
||
这是 JSON 最强大的地方,可以无限套娃。
|
||
|
||
#### 4. 对象中包含数组
|
||
比如一个学生选修了多门课。
|
||
```json
|
||
{
|
||
"student_id": 1001,
|
||
"name": "李雷",
|
||
"courses": [
|
||
"高等数学",
|
||
"大学英语",
|
||
"计算机导论"
|
||
]
|
||
}
|
||
```
|
||
|
||
#### 5. 数组中包含对象
|
||
这是最常见的数据列表格式(例如商品列表)。
|
||
```json
|
||
[
|
||
{
|
||
"id": 1,
|
||
"product": "iPhone 15",
|
||
"price": 5999
|
||
},
|
||
{
|
||
"id": 2,
|
||
"product": "AirPods",
|
||
"price": 1299
|
||
},
|
||
{
|
||
"id": 3,
|
||
"product": "MacBook",
|
||
"price": 9999
|
||
}
|
||
]
|
||
```
|
||
|
||
---
|
||
|
||
### 第三类:真实开发场景
|
||
这些是你未来写代码时最常遇到的 JSON 格式。
|
||
|
||
#### 6. 配置文件 (VS Code 风格)
|
||
很多软件的 `settings.json` 就是这样写的。
|
||
```json
|
||
{
|
||
"editor.fontSize": 14,
|
||
"editor.fontFamily": "Consolas, 'Courier New', monospace",
|
||
"editor.tabSize": 4,
|
||
"files.autoSave": "afterDelay",
|
||
"workbench.colorTheme": "Default Dark+",
|
||
"git.confirmSync": false
|
||
}
|
||
```
|
||
|
||
#### 7. 天气 API 响应数据
|
||
当你调用天气接口(如 OpenWeatherMap)时,返回的数据通常包含多层嵌套。
|
||
```json
|
||
{
|
||
"coord": {
|
||
"lon": 116.4,
|
||
"lat": 39.9
|
||
},
|
||
"weather": [
|
||
{
|
||
"id": 800,
|
||
"main": "Clear",
|
||
"description": "晴朗无云",
|
||
"icon": "01d"
|
||
}
|
||
],
|
||
"main": {
|
||
"temp": 25.5,
|
||
"feels_like": 26.1,
|
||
"humidity": 40
|
||
},
|
||
"wind": {
|
||
"speed": 3.5,
|
||
"deg": 210
|
||
},
|
||
"city": "Beijing"
|
||
}
|
||
```
|
||
|
||
#### 8. 电商订单信息
|
||
一个复杂的订单结构,包含用户信息、地址信息、商品列表(数组)和支付状态。
|
||
```json
|
||
{
|
||
"order_id": "ORD-20231024-001",
|
||
"timestamp": "2023-10-24T14:30:00Z",
|
||
"user": {
|
||
"id": 8848,
|
||
"name": "王富贵",
|
||
"vip_level": "gold"
|
||
},
|
||
"shipping_address": {
|
||
"province": "广东省",
|
||
"city": "深圳市",
|
||
"street": "深南大道100号",
|
||
"zip": "518000"
|
||
},
|
||
"items": [
|
||
{
|
||
"sku": "KB-001",
|
||
"name": "机械键盘",
|
||
"quantity": 1,
|
||
"price": 399.00
|
||
},
|
||
{
|
||
"sku": "MS-002",
|
||
"name": "无线鼠标",
|
||
"quantity": 2,
|
||
"price": 99.50
|
||
}
|
||
],
|
||
"payment": {
|
||
"method": "alipay",
|
||
"total": 598.00,
|
||
"status": "paid"
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 9. 游戏存档数据
|
||
假设你写一个 RPG 游戏,存档可能长这样。
|
||
```json
|
||
{
|
||
"player": {
|
||
"name": "DragonSlayer",
|
||
"level": 45,
|
||
"hp": 2350,
|
||
"max_hp": 2500,
|
||
"position": {
|
||
"map_id": "dungeon_03",
|
||
"x": 120.5,
|
||
"y": 45.0,
|
||
"z": -10.0
|
||
}
|
||
},
|
||
"inventory": [
|
||
{"item_id": "sword_fire", "count": 1, "durability": 85},
|
||
{"item_id": "potion_health", "count": 15},
|
||
{"item_id": "key_gold", "count": 1}
|
||
],
|
||
"quests": {
|
||
"active": [101, 104],
|
||
"completed": [1, 2, 3, 4, 100]
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 10. GeoJSON (地理信息)
|
||
这是一种专门用来描述地图数据的标准 JSON 格式。
|
||
```json
|
||
{
|
||
"type": "FeatureCollection",
|
||
"features": [
|
||
{
|
||
"type": "Feature",
|
||
"properties": {
|
||
"name": "某公园"
|
||
},
|
||
"geometry": {
|
||
"type": "Polygon",
|
||
"coordinates": [
|
||
[
|
||
[100.0, 0.0],
|
||
[101.0, 0.0],
|
||
[101.0, 1.0],
|
||
[100.0, 1.0],
|
||
[100.0, 0.0]
|
||
]
|
||
]
|
||
}
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
### 总结 JSON 的特点:
|
||
|
||
1. **极简**:只有 `{}`、`[]`、`:`、`,` 和 `""` 这几个符号。
|
||
2. **严格**:
|
||
* Example 1 中的 Key (`"username"`) 必须带双引号。
|
||
* Example 5 数组里最后一个元素后面绝对不能加逗号。
|
||
3. **万能**:无论是简单的配置,还是复杂的3D游戏坐标,都能塞进去。 |