对比解析php和go对JSON处理的区别

news/2024/11/9 1:50:30/

一、go 转化php数组代码

php程序

$str = <<<EOF
{"操作源":"任意","数据库":"任意","语句类型":"CREATE DATABASE;DROP DATABASE;ALTER DATABASE","影响行数":"不涉及","告警阈值":"执行1次"}
EOF;
$data = ['title' => '标题','list' => $str
];
$const = ['operate_account' => '操作源', 'db_name' => '数据库', 'sql_type' => '语句类型', 'rows' => '影响行数', 'alarm_line' => '告警阈值'];
$data['list'] = json_decode($data['list'], 320);$newArr2['title']=$data['title'];
foreach ($data['list'] as $key => $v) {$newArr2['content'][array_search($key,$const)]= $v;
}dd($data);
dd($newArr2);function dd($param)
{echo "<pre>";print_r($param);echo "<pre>";
}

转化go语言

package mainimport ("encoding/json""github.com/gin-gonic/gin"
)type Data struct {Title   string            `json:"title"`Content map[string]string `json:"content"`
}func main() {r := gin.Default()// 多行JSON字符串jsonStr := `{"操作源": "任意","数据库": "任意","语句类型": "CREATE DATABASE;DROP DATABASE;ALTER DATABASE","影响行数": "不涉及","告警阈值": "执行1次"}`// 转化为Go结构体var data map[string]interface{}if err := json.Unmarshal([]byte(jsonStr), &data); err != nil {panic("无法解析JSON数据")}// 定义常量映射constMap := map[string]string{"操作源":  "operate_account","数据库":  "db_name","语句类型": "sql_type","影响行数": "rows","告警阈值": "alarm_line",}// 创建新的数据结构var newArr2 DatanewArr2.Title = "标题"// 创建内容的映射newArr2.Content = make(map[string]string)// 遍历data中的数据for key, value := range data {// 查找映射关系mappedKey, exists := constMap[key]//fmt.Println(key, value, exists, constMap["数据库"], mappedKey)//os.Exit(2232)if exists {newArr2.Content[mappedKey] = value.(string)}}r.GET("/data", func(c *gin.Context) {c.JSON(200, newArr2)})r.Run(":8081")
}

转化结果:

二、go 语言中 json.Unmarshal与 json.Marshal 区别

简介
Json(Javascript Object Nanotation)是一种数据交换格式,常用于前后端数据传输。任意一端将数据转换成json 字符串,另一端再将该字符串解析成相应的数据结构,如string类型,strcut对象等。


1.Json Marshal:将数据编码成json字符串

type Stu struct {Name  string `json:"name"`Age   intsex   string  //小写的字段不可导出,所以无法序列化Class *Class `json:"class"`
}type Class struct {Name  stringGrade int
}func main() {//实例化一个数据结构,用于生成json字符串stu := Stu{Name: "张三",Age:  18,sex:  "男",}//指针变量cla := new(Class)cla.Name = "1班"cla.Grade = 3stu.Class=clajsonStu, err := json.Marshal(stu)if err != nil {fmt.Println(err.Error())}// jsonStu是[]byte类型,转化为string类型便于查看fmt.Println(string(jsonStu))
}

结果

{"name":"张三","Age":18,"class":{"Name":"1班","Grade":3}}

从结果中可以看出

  • 只要是可导出成员(变量首字母大写),都可以转成json。踩坑点:因成员变量sex是不可导出的,故无法转成json。
  • 如果变量打上了json标签,如Name旁边的 json:"name" ,那么转化成的json key就用该标签“name”,否则取变量名作为key,如“Age”,“HIgh”。
  • bool类型也是可以直接转换为json的value值。Channel, complex 以及函数不能被编码json字符串。当然,循环的数据结构也不行,它会导致marshal陷入死循环。
  • 指针变量,编码时自动转换为它所指向的值,如cla变量。(当然,不传指针,Stu struct的成员Class如果换成Class struct类型,效果也是一模一样的。只不过指针更快,且能节省内存空间。)

最后,强调一句:json编码成字符串后就是纯粹的字符串了。

总结: 将map或者结构体传入json.Marshal函数,生成json,返回类型为[]byteJson


2.Unmarshal:将json字符串解码到相应的数据结构

type StuRead struct {Name  interface{} `json:"name"`Age   interface{}HIgh  interface{}sex   interface{}Class interface{} `json:"class"`Test  interface{}
}type Class struct {Name  stringGrade int
}func main() {//json字符中的"引号,需用\进行转义,否则编译出错//json字符串沿用上面的结果,但对key进行了大小的修改,并添加了sex数据data:="{\"name\":\"张三\",\"Age\":18,\"high\":true,\"sex\":\"男\",\"CLASS\":{\"naME\":\"1班\",\"GradE\":3}}"str:=[]byte(data)//1.Unmarshal的第一个参数是json字符串,第二个参数是接受json解析的数据结构。//第二个参数必须是指针,否则无法接收解析的数据,如stu仍为空对象StuRead{}//2.可以直接stu:=new(StuRead),此时的stu自身就是指针stu:=StuRead{}err:=json.Unmarshal(str,&stu)//解析失败会报错,如json字符串格式不对,缺"号,缺}等。if err!=nil{fmt.Println(err)}fmt.Println(stu)
}

结果:

{张三 18 true <nil> map[naME:1班 GradE:3] <nil>}

总结:

json字符串解析时,需要一个“接收体”接受解析后的数据,且Unmarshal时接收体必须传递指针。否则解析虽不报错,但数据无法赋值到接受体中。如这里用的是StuRead{}接收,也可以使用map进行接收。

解析时,接收体可自行定义。json串中的key自动在接收体中寻找匹配的项进行赋值。匹配规则是:

  • 先查找与key一样的json标签,找到则赋值给该标签对应的变量(如Name)。
  • 没有json标签的,就从上往下依次查找变量名与key一样的变量,如Age。或者变量名忽略大小写后与key一样的变量。如HIgh,Class。第一个匹配的就赋值,后面就算有匹配的也忽略。
  • (前提是该变量必需是可导出的,即首字母大写)。
  • 不可导出的变量无法被解析(如sex变量,虽然json串中有key为sex的k-v,解析后其值仍为nil,即空值)
  • 当接收体中存在json串中匹配不了的项时,解析会自动忽略该项,该项仍保留原值。如变量Test,保留空值nil。
  • 你一定会发现,变量Class貌似没有解析为我们期待样子。因为此时的Class是个interface{}类型的变量,而json串中key为CLASS的value是个复合结构,不是可以直接解析的简单类型数据(如“张三”,18,true等)。所以解析时,由于没有指定变量Class的具体类型,json自动将value为复合结构的数据解析为map[string]interface{}类型的项。也就是说,此时的struct Class对象与StuRead中的Class变量没有半毛钱关系,故与这次的json解析没有半毛钱关系。

注意:若转换为结构体之后想继续操作序列化之后的字段,此时interface{}需要转化为对应的类型,使用v.(type),type为需要转化的类型。如interface.(string),使用需谨慎,类型不对会引发panic。

若结构体里有的字段不想序列化,而想保留原json,办法还是有的,我们可以将该变量定义为json.RawMessage类型,保留原json可以进行二次解析。

type StuRead struct {Name  interface{}Age   interface{}HIgh  interface{}Class json.RawMessage `json:"class"` //注意这里
}

三、应用样例参考

/*data := map[string]interface{}{"name":   "Tom","age":    18,"gender": "male",}str, err := JsonEncode(data)
*/
func JsonEncode(v interface{}) (string, error) {b, err := json.Marshal(v)if err != nil {return "", err}return string(b), nil
}/*var decodedData map[string]interface{}err = JsonDecode(str, &decodedData)
*/
func JsonDecode(s string, v interface{}) error {return json.Unmarshal([]byte(s), v)
}

参考:Go的json序列化:Marshal与Unmarshal_json marshal-CSDN博客


http://www.ppmy.cn/news/1189685.html

相关文章

剑指Offer || 080.组合

题目 给定两个整数 n 和 k&#xff0c;返回 1 ... n 中所有可能的 k 个数的组合。 示例 1: 输入: n 4, k 2 输出: [[2,4],[3,4],[2,3],[1,2],[1,3],[1,4], ] 示例 2: 输入: n 1, k 1 输出: [[1]]提示: 1 < n < 201 < k < n 注意&#xff1a;本题与主站 …

iOS使用AVCaptureSession实现音视频采集

AVCaptureSession配置采集行为并协调从输入设备到采集输出的数据流。要执行实时音视频采集&#xff0c;需要实例化采集会话并添加适当的输入和输出。 AVCaptureSession&#xff1a;管理输入输出音视频流AVCaptureDevice&#xff1a;相机硬件的接口&#xff0c;用于控制硬件特性…

axios 多个baseURL配置、实现不同前缀代理到不同的服务器的几种方式

前言&#xff1a; 在开发中&#xff0c;有可能遇到每部分的功能的需要调用另一台服务器的地址。这个时候就需要设置不同的请求前缀首先代理到不同的服务器地址。 一、axios封装实例以及代理&#xff1a;(不是完整的封装实例&#xff0c;重点在于baseURL的区别) 文件路径&…

stm32 ETH

1 How do I create a project for STM32H7 with Ethernet and LwIP stack working? STM32 LWIP 接收大数据包导致Hardfault问题解决记录 Trying to get Ethernet, LWIP and FreeRTOS working on the STM32H745. Testing on the NUCLEO-H745ZI-Q using FW_1.7 and the STM32Cub…

力扣 203 移除链表元素

目录 1.解题思路2.代码实现 1.解题思路 利用快慢指针&#xff0c;如果快指针此时的值为val则将此时满指针的next指向快指针的next利用循环&#xff0c;其次&#xff0c;要特意判断链表的头部为val的情况以及链表为空的情况. 2.代码实现 struct ListNode* removeElements(str…

JAVA深化篇_25—— 多线程介绍

多线程介绍 多线程与并发编程 什么是程序&#xff1f; 程序&#xff08;Program&#xff09;是一个静态的概念&#xff0c;一般对应于操作系统中的一个可执行文件。 什么是进程? 执行中的程序叫做进程(Process)&#xff0c;是一个动态的概念。其实进程就是一个在内存中独…

百度小程序DIY小程序源码系统+轻松创建百度小程序,实现个性化功能 带完整的搭建教程

在现在大环境的影响下&#xff0c;小程序已经成为人们日常生活中不可或缺的一部分。百度小程序作为国内领先的小程序平台之一&#xff0c;为广大开发者提供了丰富的开发资源和工具。今天源码小编就来给大家分享一款百度小程序DIY小程序源码系统。百度小程序DIY小程序源码系统是…

报错-TypeError: Cannot read properties of undefined (reading ‘url‘)

背景&#xff1a;使用pinia进行状态管理&#xff0c;优化接口调用请求时&#xff0c;报错 TypeError: Cannot read properties of undefined (reading url) TypeError:无法读取未定义的属性&#xff08;读取“url”&#xff09; 解决&#xff1a;花括号的属性未定义&#xf…