【常见开源库的二次开发】一文学懂CJSON

news2024/9/30 15:21:53

简介:

        JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。它基于JavaScript的一个子集,但是JSON是独立于语言的,这意味着尽管JSON是由JavaScript语法衍生出来的,它可以被任何编程语言读取和生成。JSON的设计目的是使数据交换既简单又快速,相对于其他数据交换格式如XML,JSON更加轻巧,这使得它在网络上传输更加高效。对于人类和机器来说,JSON文本的格式都是易于理解的。 管JSON源于JavaScript,但是几乎所有的编程语言都有解析JSON的库,这使得JSON成为跨平台和语言的数据交换的理想格式。

 一、什么是json? 

        JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。它基于JavaScript的一个子集,但是JSON是独立于语言的,这意味着尽管JSON是由JavaScript语法衍生出来的,它可以被任何编程语言读取和生成。JSON的设计目的是使数据交换既简单又快速。

1.1 JSON的特点:

         1. 轻量级:相对于其他数据交换格式如XML,JSON更加轻巧,这使得它在网络上传输更加高效。

        2. 易于阅读和编写:对于人类和机器来说,JSON文本的格式都是易于理解的。

        3. 语言无关性:尽管JSON源于JavaScript,但是几乎所有的编程语言都有解析JSON的库,这使得JSON成为跨平台和语言的数据交换的理想格式。

1.2 JSON的结构:

        1. 键值对集合(在其他语言中可能被实现为对象,记录,结构,字典,哈希表,有名列表,或者关联数组)。在JSON中,它们被表示为一个由花括号包围的对象。每个键值对由一个键(字符串)和一个值组成,键值之间用冒号分隔,键值对之间用逗号分隔。

        2. 有序的值列表(在大多数语言中被实现为数组)。在JSON中,它们被表示为由方括号包围的数组,数组的元素之间用逗号分隔。

一个简单的JSON对象示例:

{
  "name": "John Doe",
  "age": 30,
  "isEmployed": true,
  "address": {
    "street": "123 Main St",
    "city": "Anytown"
  },
  "phoneNumbers": [
    "123-456-7890",
    "987-654-3210"
  ]
}

        在这个例子中,我们有一个包含五个键值对的JSON对象。`name`、`age`和`isEmployed`键对应的值是简单的数据类型(字符串、数字和布尔值)。`address`键对应的值是一个嵌套的JSON对象,而`phoneNumbers`键对应的值是一个包含字符串的JSON数组。

1.3 基本元素

JSON(JavaScript Object Notation)的语法规则相对简单,主要包括以下几个基本元素:

        1.对象(Object):用花括号 `{}` 表示,包含一组无序的键值对。每个键值对之间用逗号分隔。键必须是字符串,值可以是任意有效的 JSON 数据类型。

     {
        "key1": "value1",
        "key2": "value2",
        "key3": "value3"
     }

        2. 数组(Array):用方括号 `[]` 表示,包含一组有序的值。每个值之间用逗号分隔。数组中的值可以是任意有效的 JSON 数据类型。

    {
        "arrayKey": [1, 2, 3, 4]
    }

        3. 值(Value):可以是字符串、数字、布尔值、对象、数组或 `null`。这些值可以嵌套在对象或数组中。

    {
        "stringKey": "Hello, JSON!",
        "numberKey": 42,
        "booleanKey": true,
        "nullKey": null,
        "objectKey": {
            "nestedKey": "nestedValue"
        },
        "arrayKey": [1, "two", false, null]
    }

        4. 字符串(String): 字符串在JSON中是由双引号 `" "` 包围的一系列Unicode字符。字符串用于表示文本数据。


        {
            "name": "John Doe",
            "city": "New York"
        }

        5. 数字(Number): 数字可以是整数或者浮点数,直接写出,不需要加引号。JSON中的数字和大多数编程语言中的表示方法相似。

        {
            "integer": 12,
            "float": 3.14
        }

        6. 布尔值(Boolean): 布尔值表示逻辑实体,只有两个值,真(`true`)或假(`false`),不需要加引号。

        {
            "isTrue": true,
            "isFalse": false
        }

        7. null: `null` 在JSON中表示空值或不存在的值。它没有引号。

        {
            "emptyValue": null
        }

具体示例:

{
    "name": "John Doe",
    "age": 30,
    "isEmployed": true,
    "address": {
        "street": "123 Main St",
        "city": "Anytown"
    },
    "phoneNumbers": [
        "123-456-7890",
        "987-654-3210"
    ]
}

在这个示例中:

        name、age 和 isEmployed 是简单的键值对,值分别是字符串、数字和布尔值。        

        address 是一个嵌套的对象,包含 street 和 city 两个键值对。

        phoneNumbers  是一个数组,包含两个字符串值。

        JSON 的简洁和易读特性使它成为数据交换和配置文件的理想选择。无论是前后端数据传递还是存储配置,JSON 都非常适用。

一个更加复杂的json:t.weather.itboy.net/api/weather/city/101010100

1.4 使用场景:

        Web开发:JSON广泛用于前后端之间的数据交换。

        配置文件:许多应用程序使用JSON格式来存储配置设置。

        API和Web服务:许多Web服务使用JSON格式来提供公共API,因为它易于被不同的编程语言读取和解析。

由于其简洁、易于理解的结构,JSON已成为Web应用和服务之间交换数据的事实标准。

 二、下载json 

下载链接:GitHub - DaveGamble/cJSON: Ultralightweight JSON parser in ANSI C

解压后得到这俩个文件 

我们需要将这俩个文件加入到vscode中的C程序文件夹中

三、创建一个json

以下是一个使用 cJSON 创建一个JSON对象的示例代码:

#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"
int main()
{
    // 创建一个新的JSON对象
    cJSON *root = cJSON_CreateObject();
    // 向根对象中添加一个名为"key1"的键值对,值为字符串"10"
    cJSON* key1 = cJSON_AddStringToObject(root,"key1","10");
    if(key1 != NULL)
    {
        printf("key:%s value :%s\n",key1->string,key1->valuestring);
    }
    // 将JSON对象转换为字符串格式
    char *str = cJSON_Print(root);  //输出json字符串
    // 打印转换后的JSON字符串
    printf(str);
    // 释放转换成字符串所使用的内存
    free(str);
    // 暂停程序运行,以便查看控制台输出
    system("pause>0");


    system("pause>0");
    return 0;
}

        在这个代码中,我们创建了一个空的JSON对象 root 

3.1 创建json对象 

    // 创建一个新的JSON对象
    cJSON *root = cJSON_CreateObject();

        cJSON_CreateObject 函数,这是 cJSON 库中用来创建一个新的JSON对象的函数。cJSON 是一个在C语言中处理JSON数据的轻量级库。

如果您想使用这个库来创建一个JSON对象,您可以按照以下步骤进行:

        1. 首先,确保已经安装了 cJSON 库。

        2. 在C语言代码中,包含 cJSON 的头文件。

        3. 使用 cJSON_CreateObject 函数来创建一个新的JSON对象。

 3.2 cjson的类型详解

cjson结构体如下定义:

/* cJSON 结构体: */
typedef struct cJSON
{
    /* next/prev 允许你在数组/对象链中遍历。或者,使用 GetArraySize/GetArrayItem/GetObjectItem */
    struct cJSON *next;
    struct cJSON *prev;
    /* 数组或对象项将有一个子指针,指向数组/对象中的项链。 */
    struct cJSON *child;

    /* 项的类型,如上所述。 */
    int type;

    /* 项的字符串,如果 type==cJSON_String 和 type == cJSON_Raw */
    char *valuestring;
    /* 写入 valueint 已被弃用,请使用 cJSON_SetNumberValue 代替 */
    int valueint;
    /* 项的数字,如果 type==cJSON_Number */
    double valuedouble;

    /* 项的名称字符串,如果此项是对象的子项,或者在对象的子项列表中。 */
    char *string;
} cJSON;

        这段代码定义了一个名为 cJSON 的结构体,这是 cJSON 库的核心数据结构,它表示一个JSON数据项。每一个 cJSON 结构体可以表示一个JSON对象、数组、字符串、数字或其他的JSON数据类型。

下面是每个成员变量的功能:

        struct cJSON *next;` 和 `struct cJSON *prev;:这两个指针分别指向相邻的JSON数据项,它们使得 cJSON 结构体可以形成一个链表,这对于表示一个JSON数组或对象是十分有用的。

        struct cJSON *child;:如果当前 cJSON 结构体表示一个JSON数组或对象,child 指针会指向一个链表,这个链表的元素就是数组或对象中的数据项。

        int type;:这个变量表示当前 cJSON 结构体表示的JSON数据类型,例如,它可能是 cJSON_NULL、cJSON_Number、cJSON_String、cJSON_Array 或 cJSON_Object 等。

        char *valuestring;:如果当前 cJSON 结构体表示一个JSON字符串,valuestring 就会被设置成那个字符串的值。如果它表示一个原始的未解析的JSON字符串,valuestring 也会被设置成那个字符串的值。

        int valueint;:这个成员现在已经不建议使用,取而代之的是 cJSON_SetNumberValue 函数来设置JSON数字的值

        double valuedouble;:如果当前 cJSON 结构体表示一个JSON数字,valuedouble 就会被设置成那个数字的值。

        char *string;:如果当前 cJSON 结构体是一个JSON对象中的数据项,string 就会被设置成那个数据项对应的键名

        我们可以使用 `cJSON` 库提供的各种函数,如 cJSON_CreateObject、cJSON_AddItemToObject 或 cJSON_GetObjectItem等,来创建、操作和查询 cJSON 结构体。

3.3 创建键值对

        cJSON_AddStringToObject 。这个函数是 cJSON 库中的一个函数,用于向一个 JSON 对象中添加一个字符串类型的键值对。

cJSON *cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);

        cJSON * const object:这是一个指向 JSON 对象的指针,表示你要往哪个对象中添加键值对。
        const char * const name:这是一个字符串,表示你要添加的键的名称(key)。

        const char * const string:这是一个字符串,表示你要添加的值(value)。

返回值:

        cJSON :这个函数返回一个指向新添加的 JSON 元素的指针。这个元素包含了添加的字符串值。如果添加失败,返回 NULL。

3.4 添加嵌套的JSON对象

        cJSON_AddItemToObject,来自 cJSON 库。函数原型应该是:

cJSON_bool cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);

        这个函数的作用是将一个 cJSON 结构(`item`),它可以代表任何类型的JSON数据(如对象、数组、字符串、数字等),添加到另一个 cJSON 对象结构中,并将其与指定的键(`string`)相关联。

参数解释如下:

        cJSON *object:这是一个指向目标JSON对象的指针,你会向它添加一个新的元素。

        const char *string:这是你想要在目标对象中创建的键的名称。

        cJSON *item:这是一个指向你想要添加的 `cJSON` 元素的指针。

返回值:

        cJSON_bool:这是一个布尔值,如果成功添加元素则返回 `cJSON_True`,否则返回 `cJSON_False`。

下面是一个使用 `cJSON_AddItemToObject` 函数添加嵌套 JSON 对象的示例:

#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"
int main()
{
    // 创建一个新的JSON对象
    cJSON *root = cJSON_CreateObject();
    // 向根对象中添加一个名为"key1"的键值对,值为字符串"10"
    cJSON* key1 = cJSON_AddStringToObject(root,"key1","10");

    cJSON* last = NULL; // 用于保存上一个添加的键值对


    for(int i = 0; i < 5; i ++)
    {
        // 创建一个名为"obj1"的子对象
        cJSON* obj1 = cJSON_CreateObject();
        // 将子对象添加到根对象中
        cJSON_AddItemToObject(root,"obj1",obj1);     
        // 向子对象中添加一个名为"key2"的键值对,值为字符串"20"
        cJSON* key2 = cJSON_AddStringToObject(obj1,"key2","20"); 
        // 将子对象添加到根对象中
        last=key2;
    }
 
    if(key1 != NULL)
    {
        printf("key:%s value :%s\n",key1->string,key1->valuestring);
    }
    // 将JSON对象转换为字符串格式
    char *str = cJSON_Print(root);  //输出json字符串
    // 打印转换后的JSON字符串
    printf(str);
    // 释放转换成字符串所使用的内存
    free(str);
    // 暂停程序运行,以便查看控制台输出
    system("pause>0");


    system("pause>0");
    return 0;
}

        在这个示例中,我们创建了一个根对象 root 和一个嵌套对象 nested,然后向嵌套对象添加了一个字符串键值对,并将嵌套对象作为根对象的一个字段添加进去。最后,我们打印并释放了相关的内存。

 四、添加数组

4.1 创建数组

cSON_PUBLIC(cSON *) cSON_CreateArray(void);

这个函数声明创建一个空的JSON数组,并返回一个指向该数组的`cJSON`指针

`cJSON_PUBLIC`是一个宏,用于定义函数的可见性,通常用于导出函数供外部使用。

函数没有参数,因此调用时不需要传递任何参数。返回值是一个指向新创建的JSON数组的指针。你可以使用这个指针来添加元素到数组中,或者将数组添加到其他JSON对象中。

示例用法:

cJSON *array = cJSON_CreateArray();
if (array == NULL) {
    fprintf(stderr, "错误: 无法创建JSON数组。\n");
    return 1;
}

// 现在你可以使用 array 指针来操作这个JSON数组

确保在使用完数组后调用`cJSON_Delete(array)`来释放内存,以避免内存泄漏。

4.2 添加元素到数组

cJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);

这个函数的作用是将一个JSON元素添加到指定的JSON数组中。函数的返回值是一个布尔值,表示添加操作是否成功。如果成功添加元素,返回true,否则返回false

参数说明:

  • cJSON *array: 这是一个指向JSON数组的指针,表示你要往哪个数组中添加元素。
  • cJSON *item: 这是一个指向要添加的JSON元素的指针。可以是任何JSON数据类型,比如字符串、数字、对象等。

我们首先创建了一个空的JSON数组和一个字符串元素,然后将字符串元素添加到数组中。如果添加操作成功,数组将包含这个新添加的元素。如果任何步骤失败,我们会打印错误信息并释放已分配的内存。

#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"

int main()
{
    // 创建一个JSON对象
    cJSON *root = cJSON_CreateObject();
    if (root == NULL) {
        fprintf(stderr, "错误: 无法创建JSON对象。\n");
        return 1;
    }

    // 定义一个整数数组
    int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    // 创建一个包含整数数组的JSON数组
    cJSON *array = cJSON_CreateIntArray(a, 10);
    if (array == NULL) {
        fprintf(stderr, "错误: 无法创建JSON数组。\n");
        cJSON_Delete(root);
        return 1;
    }

    // 将JSON数组添加到JSON对象中,键名为"array"
    cJSON_AddItemToObject(root, "array", array);

    // 将JSON对象转换为字符串并打印
    char *json_str = cJSON_Print(root);
    if (json_str != NULL) {
        printf("生成的JSON对象: \n%s\n", json_str);
        free(json_str);
    } else {
        fprintf(stderr, "错误: 无法打印JSON对象。\n");
    }

    // 释放JSON对象
    cJSON_Delete(root);

    // 暂停程序运行,以便查看控制台输出
    system("pause");

    return 0;
}
  1. 创建一个JSON对象。
  2. 定义一个整数数组。
  3. 创建一个包含整数数组的JSON数组。
  4. 将JSON数组添加到JSON对象中,键名为"array"。
  5. 将JSON对象转换为字符串并打印。
  6. 释放JSON对象。
  7. 暂停程序运行,以便查看控制台输出。

五、将JSON对象转为字符串

cSON_Print 函数的作用是将一个 cJSON 元素转换成字符串,并返回这个字符串的指针。这个函数是用于将 JSON 对象或数组转换为可读的字符串格式。

CSON_PUBLIC(char *) cSON_Print(const cSON *item);
#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"

int main()
{
    // 创建一个JSON对象
    cJSON *root = cJSON_CreateObject();
    if (root == NULL) {
        fprintf(stderr, "错误: 无法创建JSON对象。\n");
        return 1;
    }

    // 添加一些数据到JSON对象中
    cJSON_AddNumberToObject(root, "number", 123);
    cJSON_AddStringToObject(root, "string", "Hello, World!");

    // 将JSON对象转换为字符串
    char *json_str = cJSON_Print(root);
    if (json_str != NULL) {
        printf("生成的JSON字符串: \n%s\n", json_str);
        // 释放动态分配的字符串内存
        free(json_str);
    } else {
        fprintf(stderr, "错误: 无法打印JSON对象。\n");
    }

    // 释放JSON对象
    cJSON_Delete(root);

    return 0;
}

我们首先创建了一个 JSON 对象 root,并向其中添加了一个数字和一个字符串。然后,我们使用 cJSON_Print 函数将这个 JSON 对象转换为字符串,并打印出来。最后,我们释放了动态分配的字符串内存和 JSON 对象。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1913326.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

UML 2.5图的分类

新书速览|《UML 2.5基础、建模与设计实践》新书速览|《UML 2.5基础、建模与设计实践 UML 2.5在UML 2.4.1的基础上进行了结构性的调整&#xff0c;简化和重新组织了 UML规范文档。UML规范被重新编写&#xff0c;使其“更易于阅读”&#xff0c;并且“尽可能减少前向引用”。 U…

硬盘分区读不出来的应对策略与数据恢复实战

在日常的计算机使用过程中&#xff0c;硬盘分区读不出来的问题时常困扰着用户。这一故障不仅可能导致重要数据的突然失联&#xff0c;还可能对系统的稳定运行造成威胁。硬盘分区读不出来&#xff0c;往往表现为在文件资源管理器中无法访问特定分区&#xff0c;系统提示错误或分…

java中方法的使用

方法的使用 方法的概念什么是方法方法定义方法的调用过程实参和形参的关系 方法重载为什么需要方法重载方法重载的概念方法签名 递归递归的概念递归过程分析递归练习 方法的概念 什么是方法 方法就是一个代码片段&#xff0c;类似于C语言的函数。 方法存在的意义&#xff1a;…

MySQL 面试相关问题

1. MySQL 基础问题1.1 为什么用MySQL&#xff1f;1.2 表属性类型 varchar 和 char 的区别&#xff1f;1.2 什么时候用 varchar 和 char&#xff1f;1.3 Datetime 和 Timestamp 的区别&#xff1f;1.4 一个SQL语句的执行过程&#xff0c;表述下&#xff1f; 2. MySQL 存储引擎相…

Docker部署gitlab私有仓库后查看root默认密码以及修改external_url路径和端口的方法

文章目录 1、docker部署最新版gitlab2、进入gitlab容器3、修改路径地址ip和端口4、检验效果 1、docker部署最新版gitlab #docker安装命令 docker run --detach \--name gitlab \--restart always \-p 1080:80 \-p 10443:443 \-p 1022:22 \-v /gitlab/config:/etc/gitlab \-v …

预算有限?如何挑选经济适用的安全管理系统?

如今&#xff0c;无论是信息安全、生产安全还是人员安全&#xff0c;都直接关系到企业的稳定运营和长远发展。然而&#xff0c;对于许多中小企业而言&#xff0c;高昂的安全管理系统投入往往成为一大难题。那么&#xff0c;在预算有限的情况下&#xff0c;如何挑选一款既经济适…

04 效用评测层 显性指标+标准方法 对推荐效果定量评测

你好&#xff0c;我是大师兄。前面三节课我们介绍了推荐系统的数据采集层和数据加工层的相关内容&#xff0c;本节课我们重点介绍下推荐系统效用评价层的评测方法和评测指标。 这里的“效用评测”&#xff0c;通俗点说是指推荐系统输出数据的好坏是否符合用户和商业的预期&…

window 安装 openssl

文章目录 前言window 安装 openssl1. 下载2. 安装3. 配置环境变量4. 测试 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞的人每天的运气都不会太差&#xff0c;实在白嫖的话…

C++ 十进制与十六进制之间相互转换

十进制与十六进制之间相互转换 10_to_16 与二进制类似&#xff0c;十进制转十六进制对16整除&#xff0c;得到的余数的倒序即为转换而成的十六进制&#xff0c;特别地&#xff0c;如果超过10以后&#xff0c;分别用ABCDEF或abcdef来代替10、11、12、13、14、15。 代码1: #in…

Codeforces Round 954 (Div. 3) F. Non-academic Problem

思路&#xff1a;考虑缩点&#xff0c;因为是无向图&#xff0c;所以双连通分量缩完点后是一棵树&#xff0c;我们去枚举删除每一条树边的答案&#xff0c;然后取最小值即可。 #include <bits/stdc.h>using namespace std; const int N 3e5 5; typedef long long ll; …

【学术会议征稿】第四届机械自动化与电子信息工程国际学术会议(MAEIE 2024)

第四届机械自动化与电子信息工程国际学术会议&#xff08;MAEIE 2024&#xff09; 2024 4th International Conference on Mechanical Automation and Electronic Information Engineering 由安徽大学主办&#xff0c;安徽大学电气工程与自动化学院、安徽省人机共融系统与智能…

利用远程桌面进行开发,

现在的软硬件开发都涉及庞杂的软硬件环境和多种外设总线部署&#xff0c;这时我们利用远程工具和windows自带的wsl虚拟机环境再配合vscode的remote ssh远程开发模式&#xff0c;可自由的在linux windows android等平台上切换&#xff0c;让开发更顺畅&#xff0c;也可以更好的利…

数据结构--单向链表篇(python实现)

写在开头 链表&#xff08;Linked list&#xff09;是一种常见的基础数据结构&#xff0c;是一种线性表&#xff0c;但是并不会按线性的顺序存储数据&#xff0c;而是在每一个节点里存到下一个节点的指针(Pointer) 链表的优缺点 优点 不需要预先知道数据大小&#xff0c;实现灵…

简易限流实现

需求描述 写一个1秒两个的限流工具类&#xff0c;2r/s 使用semaphore 代码实现-类似令牌桶算法 public class LimitHelper {private int maxLimit;private Semaphore semaphore;private int timeoutSeconds;public LimitHelper(int maxLimit, int timeoutSeconds) {this.max…

向github远程仓库中push,要求使用token登录

Support for password authentication was removed on August 13, 2021. Please use a personal access token instead. 如上&#xff0c;当向github远程仓库push时&#xff0c;输入github的用户名和密码出现如上错误&#xff0c;要求使用token登录&#xff0c;此时只需要用户…

【uni-app+Vue3】 API请求封装:让接口调用更便捷

前言&#xff1a;uni-app是一款基于Vue.js框架的跨平台开发工具&#xff0c;可以将代码编译成H5、小程序、App等不同平台的应用。在进行uni-app开发时&#xff0c;网络请求是必不可少的环节。为了方便开发&#xff0c;我们可以封装一些网络请求方法&#xff0c;以便在多个页面中…

数据结构(初阶1.复杂度)

文章目录 一、复杂度概念 二、时间复杂度 2.1 大O的渐进表示法 2.2 时间复杂度计算示例 2.2.1. // 计算Func2的时间复杂度&#xff1f; 2.2.2.// 计算Func3的时间复杂度&#xff1f; 2.2.3.// 计算Func4的时间复杂度&#xff1f; 2.2.4.// 计算strchr的时间复杂度&#xff1f; …

RSRS研报复现——年化21.5%,含RSRS标准分,右偏标准分的Backtrader指标计算(代码+数据)

原创文章第583篇&#xff0c;专注“AI量化投资、世界运行的规律、个人成长与财富自由"。 继续Backtrader&#xff0c;今天讲讲指标扩展。 作为规则型的量化框架&#xff0c;指标是非常重要的元素&#xff0c;它是策略的基础。 我们来扩展一个经典的指标&#xff0c;RSR…

docker 安装教程

机缘 最近在开发用用到了docker,主要是将开发的项目发版到平台上&#xff0c;运用到docker发版&#xff0c;所以才会写这篇文章。 教程 1、安装Hype-v。 在安装之前&#xff0c;首先要检查下电脑系统是否安装Hyper-v功能。 注意&#xff1a;一定要检查电脑系统&#xff0c;…

在繁华与奇迹交织的深圳

在繁华与奇迹交织的深圳&#xff0c;有一本奇书悄然走红&#xff0c;它便是《华强北经济学》&#xff0c;由那位深谙市场脉搏、笔触带风的宋仕强先生所著。这本书&#xff0c;仿佛是华强北这片创业热土的缩影&#xff0c;用一个个生动鲜活的故事&#xff0c;诠释了什么是“从螺…