Files
workspace/cpp/JsonParse/Json.md
e2hang ebcee63b7c New
2026-01-09 00:05:37 +08:00

8.5 KiB
Raw Permalink Blame History

JSON(全称 JavaScript Object Notation是一种轻量级的数据交换格式

简单来说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 文件可能长这样:

{
  "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++ 中可能这样定义:

#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)

这是最基础的形式,类似于一个简单的字典。

{
  "username": "admin",
  "timeout": 5000,
  "isEnabled": true,
  "description": null
}

2. 纯数组 (Array)

JSON 也可以仅仅是一个数组,不包含最外层的键。

[
  "Monday",
  "Tuesday",
  "Wednesday",
  "Thursday",
  "Friday"
]

3. 各种数字格式

JSON 不区分整数和浮点数,统一为 Number。

{
  "integer": 42,
  "float": 3.14159,
  "negative": -10,
  "exponent": 2.5e-3
}

第二类:结构化与嵌套

这是 JSON 最强大的地方,可以无限套娃。

4. 对象中包含数组

比如一个学生选修了多门课。

{
  "student_id": 1001,
  "name": "李雷",
  "courses": [
    "高等数学",
    "大学英语",
    "计算机导论"
  ]
}

5. 数组中包含对象

这是最常见的数据列表格式(例如商品列表)。

[
  {
    "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 就是这样写的。

{
  "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返回的数据通常包含多层嵌套。

{
  "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. 电商订单信息

一个复杂的订单结构,包含用户信息、地址信息、商品列表(数组)和支付状态。

{
  "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 游戏,存档可能长这样。

{
  "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 格式。

{
  "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游戏坐标都能塞进去。