golang中json操作的完全指南
前言
JSON是一種輕量級的數據交換格式。易於閱讀和編寫。 golang 提供瞭 encoding/json 包來操作JSON數據。
1. 結構體與JSON互轉
(1)使用 json.Marshal() 方法,把結構體轉成 JSON字符串
import ( "encoding/json" "fmt" ) type Student struct { Name string Age int Skill string } func main() { stu := Student{"tom", 12, "football"} data, err := json.Marshal(&stu) if err != nil { fmt.Printf("序列化錯誤 err=%v\n", err) return } fmt.Println("序列化後: ", string(data)) }
打印: 序列化後: {“Name”:“tom”,“Age”:12,“Skill”:“football”}
(2)JSON字符串 轉 結構體,可以使用 json.Unmarshal()方法
func main() { str := `{"Name":"tom","Age":12,"Skill":"football"}` var stu2 Student err := json.Unmarshal([]byte(str), &stu2) if err != nil { fmt.Printf("反序列化錯誤 err=%v\n", err) return } fmt.Printf("反序列化後: Student=%v, Name=%v\n", stu2, stu2.Name) }
打印: 反序列化後: Student={tom 12 football}, Name=tom
(3)如何實現結構體序列化後key的名稱能自定義
對於自定義key的名稱,可以給 struct變量指定一個tag標簽
type Student struct { Name string `json:"stu_name"` Age int `json:"stu_age"` Skill string // 也可以不指定 tag標簽,默認就是 變量名稱 } func main() { stu := Student{"tom", 12, "football"} data, err := json.Marshal(&stu) if err != nil { fmt.Printf("序列化錯誤 err=%v\n", err) return } fmt.Println("序列化後: ", string(data)) }
打印後,可以看到 key的名稱已經變成瞭我們指定的 tag標簽 的名稱
序列化後: {“stu_name”:“tom”,“stu_age”:12,“Skill”:“football”}
2. map與JSON互轉
func main() { // map 轉 Json字符串 m := make(map[string]interface{}) m["name"] = "jetty" m["age"] = 16 data, err := json.Marshal(&m) if err != nil { fmt.Printf("序列化錯誤 err=%v\n", err) return } fmt.Println("序列化後: ", string(data)) // 打印: 序列化後: {"age":16,"name":"jetty"} // Json字符串 轉 map str := `{"age":25,"name":"car"}` err = json.Unmarshal([]byte(str), &m) if err != nil { fmt.Printf("反序列化錯誤 err=%v\n", err) return } fmt.Printf("反序列化後: map=%v, name=%v\n", m, m["name"]) // 打印: 反序列化後: map=map[age:25 name:car], name=car }
3. 結構體的變量不加tag標簽能否正常轉成json數據
如果變量首字母小寫,則為private。因為取不到反射信息,不能轉。
如果變量首字母大寫,則為public。不管加不加 tag 都能正常轉,加瞭tag的變量就按照tag的名稱顯示。
示例:
type User struct { Name string `json:"u_name"` age int `json:"u_age"` Skill string // 也可以不指定 tag標簽,默認就是 變量名稱 addr string } func main() { user := User{"admin", 23, "football", "上海"} data, err := json.Marshal(&user) if err != nil { fmt.Printf("序列化錯誤 err=%v\n", err) return } fmt.Println("序列化後: ", string(data)) // 打印: 序列化後: {"u_name":"admin","Skill":"football"} }
通過打印,我們發現小寫的變量,如 age、addr 都沒有轉成 json數據。
總結:
首字母小寫的不管加不加tag都不能轉為json數據,而大寫的加瞭tag可以取別名,不加tag則json內的字段跟結構體變量原名一致
4. JSON操作的一些小技巧
(1)忽略掉 struct 指定字段
type User struct { Name string `json:"u_name"` Password string `json:"password"` Email string `json:"email"` } func main() { user := User{"admin", "pwd", "[email protected]"} person := Person{23, "上海"} // 忽略掉 Password 字段 data, _ := json.Marshal(struct { *User Password string `json:"password,omitempty"` }{User: &user}) fmt.Println("忽略字段: ", string(data)) // 打印: 忽略字段: {"u_name":"admin","email":"[email protected]"} }
忽略字段: {“u_name”:“admin”,“email”:“[email protected]”}}
(2)添加額外的字段
data, _ = json.Marshal(struct { *User Skill string `json:"skill"` // 臨時添加額外的 Skill字段 }{ User: &user, Skill: "football", }) fmt.Println("添加額外字段: ", string(data))
添加額外字段: {“u_name”:“admin”,“password”:“pwd”,“email”:“[email protected]”,“skill”:“football”}
(3)合並兩個 struct
type User struct { Name string `json:"u_name"` Password string `json:"password"` Email string `json:"email"` } type Person struct { Age int Addr string `json:"addr"` } func main() { // 初始化兩個 struct user := User{"admin", "pwd", "[email protected]"} person := Person{23, "上海"} data, _ := json.Marshal(struct { *User *Person }{ User: &user, Person: &person, }) fmt.Println("合並兩個struct: ", string(data)) }
合並兩個struct: {“u_name”:“admin”,“password”:“pwd”,“email”:“[email protected]”,“Age”:23,“addr”:“上海”}
(4)字符串傳遞給 int類型
emp := struct { // 創建匿名 struct Num int `json:"num,string"` }{15,} data, _ := json.Marshal(&emp) fmt.Println("數字轉成字符串: ", string(data)) // 數字轉成字符串: {"num":"15"} str := `{"Num":"25"}` _ = json.Unmarshal([]byte(str), &emp) fmt.Printf("字符串轉成數字: Emp.Num=%v\n", emp.Num) // 字符串轉成數字: Emp.Num=25
(5)一個 json 分成兩個struct
str = ` {"u_name":"system","password":"abc","email":"[email protected]","Age":23,"addr":"杭州"}` var user2 User var person2 Person _ := json.Unmarshal([]byte(str), &struct { *User *Person }{ User: &user2, Person: &person2, }) fmt.Printf("分成兩個struct: User=%v, Person=%v\n", user2, person2)
分成兩個struct: User={system abc [email protected]}, Person={23 杭州}
補充:GoLang json格式化輸出
簡單記錄一下go語言json格式化輸出的辦法
import ( "bytes" "encoding/json" "fmt" "os" ) type Complex_Type struct{ Age int `json:"age"` Name string `json:"name"` Grades map[string]int `json:"grade"` Parents []string `json:"parents"` } grades := map[string]int{ "math" : 96, "chinese" : 87, "english" : 93, } parents := []string{ "minato", "kushina", } complex_type := Complex_Type{ Age: 18, Name: "Naruto", Grades : grades, Parents: parents, } res,err := json.Marshal(complex_type) exitOnError(err) var out bytes.Buffer err = json.Indent(&out,res,"","\t") out.WriteTo(os.Stdout) fmt.Printf("\n")
輸出:
總結
到此這篇關於golang中json操作的文章就介紹到這瞭,更多相關golang json操作內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Go語言中的Struct結構體
- Go語言中interface語法與使用詳解
- GoLang之標準庫encoding/json包
- Go遍歷struct,map,slice的實現
- golang中json小談之字符串轉浮點數的操作