package main
import (
"encoding/json"
"fmt"
)
type User struct {
Name string `json:"name"` // tag 定义 JSON 字段名
Age int `json:"age,omitempty"` // 零值时省略该字段
email string // 未导出字段:JSON 序列化会直接忽略
Tags []string `json:"tags,omitempty"`
}
func main() {
u := User{Name: "张三", Age: 0, Tags: []string{"go", "dev"}}
// Marshal:结构体 → JSON 字节
data, err := json.Marshal(u)
if err != nil {
panic(err)
}
fmt.Println(string(data))
// {"name":"张三","tags":["go","dev"]} ← age 因 omitempty 被省略,email 没出现
// Unmarshal:JSON → 结构体
raw := []byte(`{"name":"李四","age":25,"email":"hidden@x.com"}`)
var u2 User
if err := json.Unmarshal(raw, &u2); err != nil { // 必须传指针
panic(err)
}
fmt.Printf("%+v\n", u2)
// 动态解析:结构未知时用 map[string]any
var anyMap map[string]any
json.Unmarshal(raw, &anyMap)
fmt.Println(anyMap["name"])
fmt.Printf("age 的实际类型: %T\n", anyMap["age"]) // float64!JSON 数字默认解成 float64
}
步骤 7:组合实战——JSON 持久化的 todo CLI
package main
import (
"encoding/json"
"flag"
"fmt"
"os"
)
type Todo struct {
Text string `json:"text"`
Done bool `json:"done"`
}
const dataFile = "todo.json"
func load() []Todo {
data, err := os.ReadFile(dataFile)
if err != nil {
return []Todo{} // 首次运行没有文件,返回空列表
}
var todos []Todo
if err := json.Unmarshal(data, &todos); err != nil {
fmt.Fprintln(os.Stderr, "数据文件损坏:", err)
os.Exit(1)
}
return todos
}
func save(todos []Todo) {
data, err := json.MarshalIndent(todos, "", " ")
if err != nil {
panic(err)
}
if err := os.WriteFile(dataFile, data, 0644); err != nil {
panic(err)
}
}
func main() {
add := flag.String("add", "", "新增事项")
list := flag.Bool("list", false, "列出全部")
done := flag.Int("done", 0, "完成第几项")
flag.Parse()
todos := load()
switch {
case *add != "":
todos = append(todos, Todo{Text: *add})
save(todos)
fmt.Println("已添加:", *add)
case *list:
for i, t := range todos {
mark := "[ ]"
if t.Done {
mark = "[x]"
}
fmt.Printf("%d. %s %s\n", i+1, mark, t.Text)
}
case *done > 0 && *done <= len(todos):
todos[*done-1].Done = true
save(todos)
fmt.Println("已完成第", *done, "项")
default:
flag.Usage()
}
}
$ go run . -add "学完 Go 入门"
$ go run . -add "写一个 CLI"
$ go run . -list
1. [ ] 学完 Go 入门
2. [ ] 写一个 CLI
$ go run . -done 1
$ go run . -list
1. [x] 学完 Go 入门