go语言中json操作总结(下)

1. make
  • slice : make([]T, length, [capacity])

  • map : make(map[K]V, [initial_capacity])(容量只是提示,可省略)

  • chan : make(chan T, [buffer_size])

    package main

    import "fmt"

    func main() {
    // slice
    list := make([]string, 2)
    list[0] = "Go"
    fmt.Println(list) // [Go ]

    复制代码
      // map
      counts := make(map[string]int)
      counts["apple"] = 5
      fmt.Println(counts) // map[apple:5]
    
      // chan
      ch := make(chan bool, 1)
      ch <- true
      fmt.Println(<-ch) // true

    }

2. gjson & sjson 实现 dict-CRUD
复制代码
package main

import (
	"encoding/json"
	"fmt"
	"log"

	"github.com/tidwall/gjson"
	"github.com/tidwall/sjson"
)

// DynamicDict 是任意嵌套字典的类型别名
type DynamicDict = map[string]any

// ProfileManager 封装对 profile 的操作
type ProfileManager struct {
	data DynamicDict
}

// NewProfileManager 从 map 创建管理器
func NewProfileManager(initial DynamicDict) *ProfileManager {
	return &ProfileManager{data: initial}
}

// Get 查询任意路径的值,返回 gjson.Result(支持 .String(), .Int() 等)
func (pm *ProfileManager) Get(path string) gjson.Result {
	jsonBytes, err := json.Marshal(pm.data)
	if err != nil {
		log.Printf("Marshal error: %v", err)
		return gjson.Result{}
	}
	return gjson.GetBytes(jsonBytes, path)
}

// Set 修改或新增任意嵌套路径的值
func (pm *ProfileManager) Set(path string, value any) error {
	jsonBytes, err := json.Marshal(pm.data)
	if err != nil {
		return fmt.Errorf("marshal failed: %w", err)
	}

	newJSON, err := sjson.SetBytes(jsonBytes, path, value)
	if err != nil {
		return fmt.Errorf("sjson set failed: %w", err)
	}

	var newData DynamicDict
	if err := json.Unmarshal(newJSON, &newData); err != nil {
		return fmt.Errorf("unmarshal failed: %w", err)
	}

	pm.data = newData
	return nil
}

// Delete 删除指定路径的字段
func (pm *ProfileManager) Delete(path string) error {
	jsonBytes, err := json.Marshal(pm.data)
	if err != nil {
		return fmt.Errorf("marshal failed: %w", err)
	}

	newJSON, err := sjson.DeleteBytes(jsonBytes, path)
	if err != nil {
		return fmt.Errorf("sjson delete failed: %w", err)
	}

	var newData DynamicDict
	if err := json.Unmarshal(newJSON, &newData); err != nil {
		return fmt.Errorf("unmarshal failed: %w", err)
	}

	pm.data = newData
	return nil
}

// Dump 打印当前完整结构(格式化 JSON)
func (pm *ProfileManager) Dump() {
	output, _ := json.MarshalIndent(pm.data, "", "  ")
	fmt.Println(string(output))
}

// GetData 返回内部数据(可用于后续处理)
func (pm *ProfileManager) GetData() DynamicDict {
	return pm.data
}

// ====== 主程序演示 ======
func main() {
	// 初始动态嵌套字典(模拟从数据库/API 获取的用户 profile)
	initialProfile := DynamicDict{
		"id":   1001,
		"name": "Alice",
		"settings": map[string]any{
			"theme": "light",
			"lang":  "en",
			"privacy": map[string]any{
				"show_email": true,
			},
		},
		"tags": []any{"user", "beta"},
		"metadata": map[string]any{
			"created_at": "2023-01-01",
		},
	}

	// 创建管理器
	pm := NewProfileManager(initialProfile)

	fmt.Println("🟢 初始 profile:")
	pm.Dump()

	// 🔍 查询
	fmt.Println("\n🔍 查询 settings.theme:", pm.Get("settings.theme").String())
	fmt.Println("🔍 查询 privacy.show_email:", pm.Get("settings.privacy.show_email").Bool())

	// ✏️ 修改已有字段
	fmt.Println("\n✏️ 修改 settings.theme -> dark")
	_ = pm.Set("settings.theme", "dark")

	// ➕ 新增深层字段(自动创建中间层)
	fmt.Println("➕ 新增 settings.privacy.show_phone = false")
	_ = pm.Set("settings.privacy.show_phone", false)

	// ➕ 添加全新分支
	fmt.Println("➕ 新增 notifications.email.enabled = true")
	_ = pm.Set("notifications.email.enabled", true)

	// 🧪 修改数组(先设置整个数组)
	fmt.Println("🧪 设置 friends 数组")
	_ = pm.Set("friends", []any{
		map[string]any{"name": "Bob", "online": true},
		map[string]any{"name": "Carol", "online": false},
	})

	// ✏️ 修改数组中某个元素
	fmt.Println("✏️ 修改 friends.0.online -> false")
	_ = pm.Set("friends.0.online", false)

	// 🗑️ 删除字段
	fmt.Println("🗑️ 删除 tags 字段")
	_ = pm.Delete("tags")

	// 🗑️ 删除整个子对象
	fmt.Println("🗑️ 删除 metadata")
	_ = pm.Delete("metadata")

	// ✅ 最终结果
	fmt.Println("\n✅ 最终 profile:")
	pm.Dump()

	// 🔁 验证:从 manager 获取数据并访问
	final := pm.GetData()
	if settings, ok := final["settings"].(map[string]any); ok {
		if privacy, ok := settings["privacy"].(map[string]any); ok {
			fmt.Printf("\n验证: show_phone = %v\n", privacy["show_phone"])
		}
	}
}
3. gjson & sjson 实现JSON 结构(对象、数组、混合)的 CRUD
复制代码
package main

import (
	"encoding/json"
	"fmt"
	"log"

	"github.com/tidwall/gjson"
	"github.com/tidwall/sjson"
)

// GenericJSON 表示任意 JSON 值(对象、数组、字符串等)
type GenericJSON = any

// JSONManager 管理任意 JSON 数据
type JSONManager struct {
	data GenericJSON
}

// NewJSONManager 创建管理器
func NewJSONManager(initial GenericJSON) *JSONManager {
	return &JSONManager{data: initial}
}

// Get 查询路径(支持数组索引、嵌套等)
func (jm *JSONManager) Get(path string) gjson.Result {
	jsonBytes, err := json.Marshal(jm.data)
	if err != nil {
		log.Printf("Marshal error: %v", err)
		return gjson.Result{}
	}
	return gjson.GetBytes(jsonBytes, path)
}

// Set 修改或新增路径(自动处理对象/数组)
func (jm *JSONManager) Set(path string, value any) error {
	jsonBytes, err := json.Marshal(jm.data)
	if err != nil {
		return fmt.Errorf("marshal failed: %w", err)
	}

	newJSON, err := sjson.SetBytes(jsonBytes, path, value)
	if err != nil {
		return fmt.Errorf("sjson set failed: %w", err)
	}

	var newData GenericJSON
	if err := json.Unmarshal(newJSON, &newData); err != nil {
		return fmt.Errorf("unmarshal failed: %w", err)
	}

	jm.data = newData
	return nil
}

// Delete 删除路径
func (jm *JSONManager) Delete(path string) error {
	jsonBytes, err := json.Marshal(jm.data)
	if err != nil {
		return fmt.Errorf("marshal failed: %w", err)
	}

	newJSON, err := sjson.DeleteBytes(jsonBytes, path)
	if err != nil {
		return fmt.Errorf("sjson delete failed: %w", err)
	}

	var newData GenericJSON
	if err := json.Unmarshal(newJSON, &newData); err != nil {
		return fmt.Errorf("unmarshal failed: %w", err)
	}

	jm.data = newData
	return nil
}

// Dump 打印格式化 JSON
func (jm *JSONManager) Dump() {
	output, _ := json.MarshalIndent(jm.data, "", "  ")
	fmt.Println(string(output))
}

// GetData 返回原始数据
func (jm *JSONManager) GetData() GenericJSON {
	return jm.data
}

// ====== 演示各种场景 ======
func main() {
	fmt.Println("=== 场景 1: 顶层是字典(对象) ===")
	objData := map[string]any{
		"name": "Alice",
		"friends": []any{
			map[string]any{"name": "Bob", "age": 30},
			map[string]any{"name": "Carol"},
		},
	}
	mgr1 := NewJSONManager(objData)
	_ = mgr1.Set("friends.0.age", 31)
	_ = mgr1.Set("friends.1.tags", []string{"admin"})
	mgr1.Dump()

	fmt.Println("\n=== 场景 2: 顶层是列表(数组) ===")
	arrData := []any{
		map[string]any{"id": 1, "active": true},
		map[string]any{"id": 2, "active": false},
	}
	mgr2 := NewJSONManager(arrData)
	_ = mgr2.Set("0.active", false)           // 修改第一个元素的 active
	_ = mgr2.Set("1.name", "NewItem")         // 给第二个元素加字段
	_ = mgr2.Set("-1.status", "archived")     // -1 表示最后一个
	mgr2.Dump()

	fmt.Println("\n=== 场景 3: 深度混合嵌套 ===")
	complexData := map[string]any{
		"results": []any{
			map[string]any{
				"metadata": map[string]any{
					"tags": []any{"a", "b"},
				},
				"items": []any{
					map[string]any{"value": 100},
					map[string]any{"value": 200},
				},
			},
		},
	}
	mgr3 := NewJSONManager(complexData)
	_ = mgr3.Set("results.0.metadata.tags.2", "c")      // 追加到 tags
	_ = mgr3.Set("results.0.items.1.value", 250)        // 修改 items[1].value
	_ = mgr3.Set("results.0.new_flag", true)            // 新增字段
	mgr3.Dump()

	fmt.Println("\n=== 查询验证 ===")
	fmt.Println("场景1 friends.0.age =", mgr1.Get("friends.0.age").Int())
	fmt.Println("场景2 第二个元素 name =", mgr2.Get("1.name").String())
	fmt.Println("场景3 tags =", mgr3.Get("results.0.metadata.tags").String())
}
相关推荐
维天说9 小时前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json
临床数据科学和人工智能兴趣组11 小时前
RStudio的Console(控制台)是一个非常重要的组件
人工智能·机器学习·数据分析·r语言·r语言-4.2.1
Java开发追求者12 小时前
Go环境开发配置
go·go环境开发配置·环境开发配置
暖和_白开水13 小时前
数据分析agent (七):contextvars 模块上下文request_id
java·前端·数据分析
杨超越luckly16 小时前
Agent应用指南:13年与13线——武汉地铁进化史
数据分析·html·agent·可视化·地铁客流
qifuzixunzhan16 小时前
售后数据分析技巧:助力企业构建高效服务体系
数据分析·售后服务·售后管理软件·售后管理
於 兔シ18 小时前
Apache Superset 二次开发实践:接入 AI Agent,并确保数据权限不被绕过
ai·数据分析·agent·数据可视化·bi·superset·数据权限
statistican_ABin19 小时前
WHO各国预期寿命影响因素分析与轻量回归预测
大数据·人工智能·python·数据分析·回归
chatexcel19 小时前
ChatExcel入选量子位智库2026 Q2「创新AI 100」,跻身AI数据分析领域代表产品!
人工智能·数据挖掘·数据分析
程序员爱钓鱼19 小时前
配置 GoLand 与 VS Code 开发环境
前端·后端·go