
json处理
json序列化
sonic实现
go
package main
import (
"fmt"
"github.com/bytedance/sonic"
)
// 定义一个测试结构体
type User struct {
Name string `json:"name"`
Age int `json:"age"`
Addr string `json:"addr,omitempty"`
}
func main() {
// 创建一个User实例
user := User{
Name: "张三",
Age: 25,
// 不设置Addr,会被omitempty忽略
}
// 序列化:将结构体转换为JSON字符串
jsonStr, err := sonic.Marshal(user)
if err != nil {
fmt.Printf("序列化失败: %v\n", err)
return
}
fmt.Printf("序列化结果: %s\n", jsonStr)
// 反序列化:将JSON字符串转换为结构体
var newUser User
err = sonic.Unmarshal(jsonStr, &newUser)
if err != nil {
fmt.Printf("反序列化失败: %v\n", err)
return
}
fmt.Printf("反序列化结果: Name=%s, Age=%d\n", newUser.Name, newUser.Age)
/**
序列化结果: {"name":"张三","age":25}
反序列化结果: Name=张三, Age=25
*/
}
原生实现
格式化
注意,结构体的字段必须是大写的,否者json输出不认,好难受
go
package main
import (
"encoding/json"
"fmt"
)
type IT struct {
// 结构体变量一定要大写,否则获取不到
Company string
Subjects []string
IsOK bool
Score float64
}
/*
*
结构体/map-=json.Marshal=>[]byte-=string()=>string
*/
func main() {
s := IT{"itcast", []string{"Go", "C++", "Java"}, false, 6.4}
//buf, err := json.Marshal(s);
buf, err := json.MarshalIndent(s, "", " ") // indent最好4个空格,累容
// buf是byte类型
if err != nil {
fmt.Println("err =", err)
return
}
fmt.Println("buf =", string(buf))
/**
buf = {
"Company": "itcast",
"Subjects": [
"Go",
"C++",
"Java"
],
"IsOK": false,
"Score": 6.4
}
*/
// 通过map生成json
map1 := make(map[string]interface{}, 4)
map1["Company"] = "q"
map1["Subjects"] = 13
map1["IsOK"] = IT{"itcast", []string{"Go", "C++", "Java"}, false, 6.4}
map1["a"] = [...]int{1, 3, 6, 9}
buf, err = json.Marshal(map1)
if err != nil {
fmt.Println("err =", err)
return
}
fmt.Println("buf =", string(buf)) //buf = {"Company":"q","IsOK":{"Company":"itcast","Subjects":["Go","C++","Java"],"IsOK":false,"Score":6.4},"Subjects":13,"a":[1,3,6,9]}
}
struct tag
就是对字段特殊处理一下
go
package main
import (
"encoding/json"
"fmt"
)
type IT struct {
// 结构体变量一定要大写,否则获取不到
Company string `json:"-"` // 此字段不会输出到屏幕
Subjects []string `json:"subjects"` // 二次编码
IsOK bool `json:",string"` //
Score float64
}
func main() {
s := IT{"itcast", []string{"Go", "C++", "Java"}, false, 6.4}
//buf, err := json.Marshal(s);
buf, err := json.MarshalIndent(s, "", " ") // indent最好4个空格,累容
if err != nil {
fmt.Println("err =", err)
return
}
fmt.Println("buf =", string(buf))
/**
buf = {
"subjects": [
"Go",
"C++",
"Java"
],
"IsOK": "false",
"Score": 6.4
}
*/
// 创建一个保存键值对的映射
t1 := make(map[string]interface{})
t1["company"] = "itcast"
t1["subjects "] = []string{"Go", "C++", "Python", "Test"}
t1["isok"] = true
t1["price"] = 666.666
b, err := json.Marshal(t1)
//json.MarshalIndent(t1, "", "")
if err != nil {
fmt.Println("json err:", err)
}
fmt.Println(string(b))
//输出结果:{"company":"itcast","isok":true,"price":666.666,"subjects ":["Go","C++","Python","Test"]}
}
json字符串转结构体
go
package main
import (
"encoding/json"
"fmt"
)
type IT struct {
// 结构体变量一定要大写,否则获取不到
Company string
Subjects []string
IsOK bool
Score float64
}
func main() {
s := "{\"Company\": \"kakaluote\",\"Subjects\": [\"Go\",\"C++\",\"Java\"],\"IsOK\": false,\"Score\": 6.4}"
// 解析到结构体
var tmp IT
fmt.Println("s =", s)
err := json.Unmarshal([]byte(s), &tmp)
if err != nil {
fmt.Println("err =", err)
return
}
fmt.Println(tmp)
// 解析到map
map1 := make(map[string]interface{}, 4)
err = json.Unmarshal([]byte(s), &map1)
if err != nil {
fmt.Println("err =", err)
return
}
fmt.Println(map1)
fmt.Println("str =", map1["Company"]) // 视频上说这里会报错,需要使用类型断言
for key, value := range map1 {
fmt.Printf("key = %v, value = %v...", key, value)
switch value.(type) { // 类型断言的标准写法
case string:
fmt.Printf("the type of map[%s] is string", key)
break
case int:
fmt.Printf("the type of map[%s] is int", key)
break
case []string: // 匹配不到
fmt.Printf("the type of map[%s] is []string", key)
break
case []interface{}: // 这才能匹配到
fmt.Printf("the type of map[%s] is []interface", key)
break
case bool:
fmt.Printf("the type of map[%s] is bool", key)
break
case float64:
fmt.Printf("the type of map[%s] is float64", key)
break
}
fmt.Printf("\n")
}
/***
s = {"Company": "kakaluote","Subjects": ["Go","C++","Java"],"IsOK": false,"Score": 6.4}
{kakaluote [Go C++ Java] false 6.4}
map[Company:kakaluote IsOK:false Score:6.4 Subjects:[Go C++ Java]]
str = kakaluote
key = Company, value = kakaluote...the type of map[Company] is string
key = Subjects, value = [Go C++ Java]...the type of map[Subjects] is []interface
key = IsOK, value = false...the type of map[IsOK] is bool
key = Score, value = 6.4...the type of map[Score] is float64
*/
}
Json字符串转Map
go
package main
import (
"encoding/json"
"fmt"
"log"
)
func main() {
// JSON 字符串
jsonString := `{"uid": "uid001", "did": "did001", "test_result": "pass"}`
// 定义一个 map[string]string 来接收反序列化结果
var data map[string]interface{}
// 反序列化
err := json.Unmarshal([]byte(jsonString), &data)
if err != nil {
log.Fatalf("JSON 反序列化失败: %v", err)
}
// 使用结果
fmt.Printf("反序列化结果: %+v\n", data)
fmt.Printf("uid: %s\n", data["uid"])
fmt.Printf("did: %s\n", data["did"])
fmt.Printf("test_result: %s\n", data["test_result"])
}
两个json合并
go
package main
import (
"encoding/json"
"fmt"
)
// mergeJSONStrings 将两个 JSON 字符串解析并合并为一个 map,然后返回合并后的 JSON 字符串
func mergeJSONStrings(str1, str2 string) (string, error) {
// 1. 创建一个通用的 map 来存储合并后的结果
merged := make(map[string]interface{})
// 2. 解析第一个 JSON 字符串
var data1 map[string]interface{}
if err := json.Unmarshal([]byte(str1), &data1); err != nil {
return "", fmt.Errorf("解析第一个 JSON 失败: %w", err)
}
// 3. 解析第二个 JSON 字符串
var data2 map[string]interface{}
if err := json.Unmarshal([]byte(str2), &data2); err != nil {
return "", fmt.Errorf("解析第二个 JSON 失败: %w", err)
}
// 4. 将两个 map 的键值对合并到 merged 中
// 先合并 data1
for k, v := range data1 {
merged[k] = v
}
// 再合并 data2,如果 key 已存在,则覆盖(后者的优先)
for k, v := range data2 {
merged[k] = v
}
// 5. 将合并后的 map 序列化为 JSON 字符串
resultBytes, err := json.Marshal(merged)
if err != nil {
return "", fmt.Errorf("序列化合并结果失败: %w", err)
}
return string(resultBytes), nil
}
func main() {
// 定义两个 JSON 字符串
str1 := `{"did":"did001","test_result":"pass","uid":"uid001"}`
str2 := `{"task_url":"https://xxxxxx/auto_test/inner/redirect/report"}`
// 调用合并函数
mergedJSON, err := mergeJSONStrings(str1, str2)
if err != nil {
panic(err) // 实际项目中应更优雅地处理错误
}
// 输出结果
fmt.Println("合并后的 JSON:")
fmt.Println(mergedJSON)
}