外观
JSON 处理
约 537 字大约 2 分钟
2025-06-19
本文整理了 Go 语言中
encoding/json包的常用操作,包括 struct/map/[]byte 与 JSON 字符串的互转。
struct ↔ JSON
JSON 字符串 → struct
package main
import (
"encoding/json"
"fmt"
)
type Config struct {
Host string `json:"host"`
Port int `json:"port"`
StaticDir string `json:"static_dir"`
Templates []string `json:"templates"`
}
func main() {
jsonStr := `{
"host": "localhost:9090",
"port": 9090,
"static_dir": "/var/www/static",
"templates": ["index.html", "base.html"]
}`
var cfg Config
if err := json.Unmarshal([]byte(jsonStr), &cfg); err != nil {
panic(err)
}
fmt.Println(cfg.Host) // localhost:9090
fmt.Println(cfg.Port) // 9090
}要点:
- struct 字段必须首字母大写(导出),才能被
encoding/json访问 - 通过
json:"xxx"tag 指定 JSON 键名,可忽略大小写限制 - 使用
json:"-"可跳过某个字段
struct → JSON 字符串
cfg := Config{
Host: "localhost:9090",
Port: 9090,
StaticDir: "/var/www/static",
}
data, err := json.Marshal(cfg)
if err != nil {
panic(err)
}
fmt.Println(string(data))
// {"host":"localhost:9090","port":9090,"static_dir":"/var/www/static","templates":null}美化输出(缩进格式化)
data, _ := json.MarshalIndent(cfg, "", " ")
fmt.Println(string(data))
// {
// "host": "localhost:9090",
// "port": 9090,
// "static_dir": "/var/www/static",
// "templates": null
// }map ↔ JSON
JSON → map
jsonStr := `{"name": "go", "version": 1.20}`
var m map[string]interface{}
json.Unmarshal([]byte(jsonStr), &m)
fmt.Println(m["name"]) // go
fmt.Println(m["version"]) // 1.2map → JSON
m := map[string]interface{}{
"name": "go",
"version": 1.20,
}
data, _ := json.Marshal(m)
fmt.Println(string(data))
// {"name":"go","version":1.2}注意: map 的 key 是无序的,Marshal 后 JSON 的顺序可能与预期不同。
slice ↔ JSON
// []string → JSON
langs := []string{"Go", "Python", "Java"}
data, _ := json.Marshal(langs)
fmt.Println(string(data))
// ["Go","Python","Java"]
// JSON → []string
var result []string
json.Unmarshal(data, &result)
fmt.Println(result)
// [Go Python Java]常用 tag 说明
| Tag | 作用 |
|---|---|
json:"name" | 指定字段名为 name |
json:"name,omitempty" | 字段为空时省略该字段 |
json:",omitempty" | 使用字段原名,空值时省略 |
json:"-" | 完全忽略该字段 |
omitempty 示例
type User struct {
Name string `json:"name"`
Email string `json:"email,omitempty"` // 空值时不输出
}
u := User{Name: "Alice"}
data, _ := json.Marshal(u)
fmt.Println(string(data))
// {"name":"Alice"}读取 JSON 文件
package main
import (
"encoding/json"
"fmt"
"os"
)
func main() {
data, err := os.ReadFile("config.json")
if err != nil {
panic(err)
}
var cfg Config
if err := json.Unmarshal(data, &cfg); err != nil {
panic(err)
}
fmt.Println(cfg.Host)
}流式读写大 JSON
import (
"bytes"
"encoding/json"
"os"
)
// 写入 JSON 到文件
buf := new(bytes.Buffer)
enc := json.NewEncoder(buf)
enc.SetIndent("", " ")
enc.Encode(cfg)
os.WriteFile("out.json", buf.Bytes(), 0644)
// 从文件逐行解析 JSON
file, _ := os.Open("data.json")
defer file.Close()
dec := json.NewDecoder(file)
for dec.More() {
var item Config
dec.Decode(&item)
fmt.Println(item.Host)
}