**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 #include #include #include struct JsonValue; // 前向声明 // 定义 JSON 支持的类型 using JsonVariant = std::variant< std::nullptr_t, bool, double, std::string, std::vector, // 数组 std::map // 对象 >; 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游戏坐标,都能塞进去。